线段树,几何知识很重要啊,左子树会对右子树产生影响 #include<iostream> #include<cmath> using namespace std; #define DEBUG_ENABLE 1 #define eps 1e-8 #define MAXN 10005 const double PI = (acos(-1.0)); int sum[MAXN]; int len[MAXN]; struct point{ double x,y; point operator + (point a){ point ret; ret.x=x+a.x; ret.y=y+a.y; return ret; } point operator - (point a){ point ret; ret.x=x-a.x; ret.y=y-a.y; return ret; } }; struct SegmentTree{ int left[MAXN*4],right[MAXN*4]; point ep[MAXN*4],sp[MAXN*4]; char add[MAXN*4]; int angle[MAXN*4]; inline void build(int k,int l,int r){ left[k]=l; right[k]=r; add[k]=0; angle[k]=0; sp[k].x=0;sp[k].y=sum[l]-len[l]; ep[k].x=0;ep[k].y=sum[r]; if(l==r) return ; int m=(l+r)>>1; build(k*2,l,m); build(k*2+1,m+1,r); } inline void push_up(int k){ if(left[k]!=right[k]){ sp[k]=sp[k*2]; ep[k]=ep[k*2+1]; } return ; } inline void push_down(int k){ if(add[k]){ //update left node add[k*2]=1; angle[k*2]=(angle[k*2]+angle[k])%360; ep[k*2]=sp[k]+(ep[k*2]-sp[k*2]); sp[k*2]=sp[k]; turn(k*2,angle[k]); //update right node ep[k*2+1]=ep[k*2]+(ep[k*2+1]-sp[k*2+1]); sp[k*2+1]=ep[k*2]; add[k*2+1]=1; angle[k*2+1]=(angle[k*2+1]+angle[k])%360; turn(k*2+1,angle[k]); add[k]=0; angle[k]=0; } } inline void turn(int k,int a){ point tmp; tmp.x=ep[k].x-sp[k].x; tmp.y=ep[k].y-sp[k].y; ep[k].x=sp[k].x+tmp.x*cos(a*PI/180.0)-tmp.y*sin(a*PI/180.0); ep[k].y=sp[k].y+tmp.x*sin(a*PI/180.0)+tmp.y*cos(a*PI/180.0); return ; } inline void update(int k,int l,int a){ if(left[k]>=l){ add[k]=1; angle[k]=(angle[k]+a)%360; turn(k,a); return ; } push_down(k); int m=(left[k]+right[k])>>1; if(l<=m){ update(k*2,l,a); ep[k*2+1]=ep[k*2]+(ep[k*2+1]-sp[k*2+1]); sp[k*2+1]=ep[k*2]; update(k*2+1,l,a); } else{ update(k*2+1,l,a); } push_up(k); } inline int query(int k,int l){ if(left[k]==l&&right[k]==l) return angle[k]; else{ push_down(k); int m=(left[k]+right[k])>>1; int ret; if(l<=m) ret=query(k*2,l); else ret=query(k*2+1,l); push_up(k); return ret; } } inline void run(int n,int m){ int i; for(i=1;i<=m;i++){ int ind,angle; scanf("%d%d",&ind,&angle); angle=(angle-(180+(360+query(1,ind+1)-query(1,ind))%360)%360+360)%360; // angle=((180-query(1,ind+1)+query(1,ind)+angle)%360+360)%360; update(1,ind+1,angle); printf("%.2lf %.2lf/n",ep[1].x+eps,ep[1].y+eps); } } #if (DEBUG_ENABLE == 1) inline void debug(int k){ printf("ID = %2d, 左儿子 = %2d, 右儿子 = %2d, left = %2d, right = %2d, start = (%.2lf,%.2lf), end = (%.2lf,%.2lf), angle = %2d/n",k,k*2,k*2+1,left[k],right[k],sp[k].x,sp[k].y,ep[k].x,ep[k].y,angle[k]); if(left[k]==right[k]) return ; debug(k*2); debug(k*2+1); } #endif }sgt; int main() { int n,c; int cas=0; while(scanf("%d%d",&n,&c)!=EOF){ int i; sum[0]=len[0]=0; for(i=1;i<=n;i++){ scanf("%d",&len[i]); sum[i]=sum[i-1]+len[i]; } if(cas) puts(""); cas=1; sgt.build(1,1,n); sgt.run(n,c); } }