LightOJ-2991-线段树

来源:互联网 发布:淘宝客如意投怎么设置 编辑:程序博客网 时间:2024/05/21 01:44

题目大意:有个n条线段组成的起重机,有m次询问,每次询问将第Si-Si+1之间的角度变为degree,问起点到终点的向量是多少;

题目解析:线段树好题,把它想象成一个一个区间[l,r],我们需要维护从l到r的向量和角度;如果我们要是一条折线旋转一个角度,就等于其中各个向量旋转一样的角度,还有一个细节就是线段树的懒操作(用到的时候我再更新)sd[];

AC代码:

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<string>#include<cmath>#define PI acos(-1.0);using namespace std;const int maxn=10010;int sd[maxn<<2],degree[maxn];double sx[maxn<<2],sy[maxn<<2];void roate(int n,int d){double deg=d* asin(1.0) /90.0;double x=cos(deg)*sx[n]-sin(deg)*sy[n];double y=sin(deg)*sx[n]+cos(deg)*sy[n];sx[n]=x;sy[n]=y;}void pushdown(int n){roate(n<<1,sd[n]);roate(n<<1|1,sd[n]);sd[n<<1]+=sd[n];sd[n<<1|1]+=sd[n];sd[n]=0;}void pushup(int n){sx[n]=sx[n<<1]+sx[n<<1|1];sy[n]=sy[n<<1]+sy[n<<1|1];}void build(int l,int r,int n){sd[n]=0;if(l==r){scanf("%lf",&sy[n]);sx[n]=0;return ;}int mid=(l+r)>>1;build(l,mid,n<<1);build(mid+1,r,n<<1|1);pushup(n);}void update(int p,int d,int l,int r,int n){if(p<l){roate(n,d);sd[n]+=d;return ;}if(sd[n])pushdown(n);int mid=(l+r)>>1;if(p<mid)update(p,d,l,mid,n<<1);update(p,d,mid+1,r,n<<1|1);pushup(n);}int main(){int n,m,flag=0,d,in,i;while(scanf("%d%d",&n,&m)!=EOF){if(flag) puts("");else flag=1;build(1,n,1);for(i=1;i<=n;i++)degree[i]=180;while(m--){scanf("%d%d",&in,&d);update(in,d-degree[in],1,n,1);degree[in]=d; printf("%.2lf %.2lf\n",fabs(sx[1])<1e-8?0:sx[1],fabs(sy[1])<1e-8?0:sy[1]);  }}return 0;}



0 0
原创粉丝点击