Time Limit: 2000MS | Memory Limit: 65536K | |||
Total Submissions: 3962 | Accepted: 1072 | Special Judge |
Description
Input
Output
Sample Input
2 1 10 5 1 90 3 2 5 5 5 1 270 2 90
Sample Output
5.00 10.00 -10.00 5.00 -5.00 10.00
吊车有N截,最开始都在y轴上,M个操作,把s+1以上部分旋转,使s和s+1角度为a,每次操作后输出最高一截顶部的坐标。
线段树x,y维护当前区间从头连到尾的向量,degree为相对于坐标轴的旋转角度,setv为要pushdown的角度。每次操作先询问当前第s+1截和s截的角度,做差,再用a减去这个角度就是要旋转的角度。然后在[s+1,N]区间update这个角度。
逆时针旋转公式:x'=cosa*x-sina*y,y'=sina*x+cosa*y。
每次操作后输出tree.x[1],tree.y[1]。
#include<iostream> #include<queue> #include<cstring> #include<cstdio> #include<cmath> #include<set> #include<map> #include<vector> #include<stack> #include<algorithm> #define pi (4*atan(1.0)) typedef long long LL; using namespace std; const int MAXN=10010; const int MAXNODE=4*MAXN; int N,M,Y[MAXN]; struct SegmentTree{ double x[MAXNODE],y[MAXNODE]; int setv[MAXNODE],degree[MAXNODE]; void maintain(int o){ x[o]=x[o<<1]+x[o<<1|1]; y[o]=y[o<<1]+y[o<<1|1]; } void build(int o,int L,int R){ setv[o]=0; if(L>=R){ y[o]=Y[L]; x[o]=0; degree[L]=0; return; } int mid=L+(R-L)/2; build(o<<1,L,mid); build(o<<1|1,mid+1,R); maintain(o); } void rotate(double& x,double& y,int deg){ double tmpx=x,tmpy=y,a=deg/180.0*pi; x=tmpx*cos(a)-tmpy*sin(a); y=tmpx*sin(a)+tmpy*cos(a); } void pushdown(int o,int L,int R){ if(setv[o]>0){ setv[o<<1]=(setv[o<<1]+setv[o])%360; setv[o<<1|1]=(setv[o<<1|1]+setv[o])%360; int mid=L+(R-L)/2; if(L>=mid) degree[L]=(degree[L]+setv[o])%360; if(mid+1>=R) degree[R]=(degree[R]+setv[o])%360; rotate(x[o<<1],y[o<<1],setv[o]); rotate(x[o<<1|1],y[o<<1|1],setv[o]); setv[o]=0; } } void update(int o,int L,int R,int ql,int qr,int deg){ if(ql<=L&&qr>=R){ setv[o]=(setv[o]+deg)%360; if(L>=R) degree[L]=(degree[L]+deg)%360; rotate(x[o],y[o],deg); return; } pushdown(o,L,R); int mid=L+(R-L)/2; if(ql<=mid) update(o<<1,L,mid,ql,qr,deg); if(qr>mid) update(o<<1|1,mid+1,R,ql,qr,deg); maintain(o); } int query(int o,int L,int R,int pos){ if(L>=R) return degree[L]; pushdown(o,L,R); int mid=L+(R-L)/2; if(pos<=mid) return query(o<<1,L,mid,pos); else return query(o<<1|1,mid+1,R,pos); } }tree; int main(){ freopen("in.txt","r",stdin); int cas=0; while(scanf("%d%d",&N,&M)!=EOF){ if(cas++) puts(""); for(int i=1;i<=N;i++) scanf("%d",&Y[i]); tree.build(1,1,N); int s,deg; while(M--){ scanf("%d%d",&s,°); int tmp=(180+tree.query(1,1,N,s+1)-tree.query(1,1,N,s)+360)%360; tree.update(1,1,N,s+1,N,(deg-tmp+360)%360); printf("%.2lf %.2lf\n",tree.x[1],tree.y[1]); } } return 0; }