poj crane

  1 #include<stdio.h>
  2 #include<math.h>
  3 #include<string.h>
  4 #include<stdlib.h>
  5 #define N (10010<<2)
  6 #define maxn 10000
  7 #define lson l,m,rt<<1
  8 #define rson m+1,r,rt<<1|1
  9 #define pi acos(-1.0)
 10 
 11 int ang[N];
 12 double x[N],y[N],len[maxn+1];
 13 
 14 void Rotate(int rt,double rad)
 15 {
 16     double s=x[rt],t=y[rt];
 17     x[rt]=s*cos(rad)-t*sin(rad);
 18     y[rt]=s*sin(rad)+t*cos(rad);
 19 }
 20 
 21 double getrad(double x)
 22 {
 23     return x*pi/180.0;
 24 }
 25 
 26 void PushDown(int rt)
 27 {
 28     if(ang[rt])
 29     {
 30         ang[rt<<1]+=ang[rt];
 31         ang[rt<<1|1]+=ang[rt];
 32         double rad=getrad(ang[rt]);
 33         ang[rt]=0;
 34         Rotate(rt<<1,rad);
 35         Rotate(rt<<1|1,rad);
 36     }
 37 }
 38 
 39 void PushUp(int rt)
 40 {
 41     x[rt]=x[rt<<1]+x[rt<<1|1];
 42     y[rt]=y[rt<<1]+y[rt<<1|1];
 43 }
 44 
 45 void build(int l,int r,int rt)
 46 {
 47     ang[rt]=0;
 48     if(l==r)
 49     {
 50         x[rt]=0;
 51         y[rt]=len[l];
 52         return ;
 53     }
 54     int m=(l+r)>>1;
 55     build(lson);
 56     build(rson);
 57     PushUp(rt);
 58 }
 59 
 60 void update(int p,int del,int l,int r,int rt)
 61 {
 62     if(l==r)
 63     {
 64         double rad=getrad(del);
 65         Rotate(rt,rad);
 66         return;
 67     }
 68     int m=(l+r)>>1;
 69     PushDown(rt);
 70     if(p<=m)
 71     {
 72         double rad=getrad(del);
 73         update(p,del,lson);
 74         Rotate(rt<<1|1,rad);
 75         ang[rt<<1|1]+=del;
 76     }
 77     else
 78         update(p,del,rson);
 79     PushUp(rt);
 80 }
 81 
 82 int main(void)
 83 {
 84     int n,q;
 85     int flag=0;
 86     int index,degree[maxn+1],d;
 87     while(~scanf("%d%d",&n,&q))
 88     {
 89         memset(degree,0,sizeof(degree));
 90         memset(ang,0,sizeof(ang));/*旋转角度初始化为0,也就是一开始不旋转,这一步也可以放在build函数里面进行,不能遗漏*/
 91         if(flag) puts("");
 92         else flag=1;
 93         for(int i=1; i<=n; i++)
 94             scanf("%lf",len+i);
 95         build(1,n,1);
 96         while(q--)
 97         {
 98           scanf("%d%d",&index,&d);
 99           d-=180;
100           index++;/*index要先增加,然后再和degree[intdex]求旋转角度*/
101           int delta=d-degree[index];
102           degree[index]=d;
103           update(index,delta,1,n,1);
104           printf("%.2f %.2f
",x[1],y[1]);
105         }
106     }
107     return 0;
108 }

 关于Rotae函数是这样理解的,更新时表示index+1段之后的线段绕index段末端点旋转delta度,x,y分别对应index+1之后的线段在x轴,y轴上投影。
根据x'=x*cos(rad)-y*sin(rad),y'=x*sin(rad)+y*cos(rad)可以将旋转后的投影算出来。

原文地址:https://www.cnblogs.com/rootial/p/3249597.html