題意:有N根杆子,前後兩根杆子通過一個節點串連,每個節點可以旋轉一定的角度,每次給你一個操作(s,a)表示將第S與S+1之間的角度修改為a度,並且每次操作之後都需要求出第N個節點的位置。
首先,最後一個節點的座標(即位置)可以通過所有杆子末尾的座標相加得到(這跟向量相加很類似)。因為每次更新需要修改S和S+1的位置,所以我們需要知道每次更新之後S和S+1的角度——查詢操作,知道之後,再根據這次需要修改的角度a,得到S+1到最後一段杆子需要改變的角度——更新操作。最後輸出答案即所以節點的x座標和,y座標和。線段樹結點裡的flag即是延遲標記。
#include <iostream>#include <cstring>#include <cstdio>#include <cmath>#define PI (acos(-1.0))#define LL(x) (x<<1)#define RR(x) (x<<1|1)#define MID(a,b) (a+((b-a)>>1))const int N=10010;using namespace std;struct node{int lft,rht;int flag,angle;double x,y;int mid(){return MID(lft,rht);}void fun(int valu){flag=(flag+valu)%360;angle=(angle+valu)%360;double tmpx=x,tmpy=y;x=cos(valu/180.0*PI)*tmpx-sin(valu/180.0*PI)*tmpy;y=sin(valu/180.0*PI)*tmpx+cos(valu/180.0*PI)*tmpy;}};int n,m;int len[N];struct Segtree{node tree[N*4];void up(int ind){tree[ind].x=tree[LL(ind)].x+tree[RR(ind)].x;tree[ind].y=tree[LL(ind)].y+tree[RR(ind)].y;}void down(int ind){if(tree[ind].flag){tree[LL(ind)].fun(tree[ind].flag);tree[RR(ind)].fun(tree[ind].flag);tree[ind].flag=0;}}void build(int lft,int rht,int ind){tree[ind].lft=lft;tree[ind].rht=rht;tree[ind].angle=tree[ind].flag=0;if(lft==rht){tree[ind].x=0;tree[ind].y=len[lft];}else{int mid=tree[ind].mid();build(lft,mid,LL(ind));build(mid+1,rht,RR(ind));up(ind);}}void updata(int st,int ed,int ind,int valu){int lft=tree[ind].lft,rht=tree[ind].rht;if(st<=lft&&rht<=ed) tree[ind].fun(valu);else{down(ind);int mid=tree[ind].mid();if(st<=mid) updata(st,ed,LL(ind),valu);if(ed> mid) updata(st,ed,RR(ind),valu);up(ind);}}int query(int pos,int ind){if(tree[ind].lft==tree[ind].rht) return tree[ind].angle;else{down(ind);int mid=tree[ind].mid(),ang;if(pos<=mid) ang=query(pos,LL(ind));else ang=query(pos,RR(ind));up(ind);return ang;}}}seg;int main(){int t_cnt=0;while(scanf("%d%d",&n,&m)!=EOF){int s,a;for(int i=1;i<=n;i++) scanf("%d",&len[i]);seg.build(1,n,1);if(t_cnt++!=0) puts("");for(int i=0;i<m;i++){scanf("%d%d",&s,&a);int a1=seg.query(s,1);int a2=seg.query(s+1,1);int ang=(a-((180+a2-a1+360)%360))%360;seg.updata(s+1,n,1,ang);printf("%.2lf %.2lf\n",seg.tree[1].x,seg.tree[1].y);}}return 0;}