POJ2991

题目链接:https://vjudge.net/problem/POJ-2991

知识准备:

1、向量旋转公式:向量(x,y)逆时针旋转角度A,则旋转后的向量为(x*cos A-y*sin A, x*sin A+y*cos A).

详见:https://www.zybang.com/question/143ceaa20d3942f3c6dbe9415dd81d0a.html

2、PI可用这一行代码取得:

const double PI=acos(-1.0);

解题思路:思路来源于:http://www.cnblogs.com/staginner/archive/2012/04/07/2436436.html。

在此处 struct point pt[rt] 是rt对应的向量的坐标。

以结点间的向量为基础建立线段树。

第48行,if()里面的判断条件是个易错点,一开始没有把l-1,所以错了。

这是一道好题,值得重复做。

AC代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <cmath>
 5 using namespace std;
 6 #define lson l,m,rt<<1
 7 #define rson m+1,r,rt<<1|1
 8 const int maxn=10000+3;
 9 const double PI=acos(-1.0);
10 int totlen[maxn],len[maxn],degree[maxn];
11 int rd[maxn<<2];
12 int n,c;
13 struct point{
14     double x,y;
15 }pt[maxn<<2];
16 double getrad(int a){
17     return (double)a/180*PI;
18 }
19 void Rotate(double &dx,double &dy,double rad){
20     double x=dx,y=dy;
21     dx=x*cos(rad)-y*sin(rad);
22     dy=x*sin(rad)+y*cos(rad);
23 }
24 void pushup(int rt){
25     pt[rt].x=pt[rt<<1].x+pt[rt<<1|1].x;
26     pt[rt].y=pt[rt<<1].y+pt[rt<<1|1].y;
27 }
28 void pushdown(int rt){
29     if(rd[rt]){
30         double rad=getrad(rd[rt]);
31         rd[rt<<1]+=rd[rt];
32         rd[rt<<1|1]+=rd[rt];
33         Rotate(pt[rt<<1].x,pt[rt<<1].y,rad);
34         Rotate(pt[rt<<1|1].x,pt[rt<<1|1].y,rad);
35         rd[rt]=0;
36     }
37 }
38 void build(int l,int r,int rt){
39     rd[rt]=0;
40     pt[rt].x=0;     pt[rt].y=totlen[r]-totlen[l-1];
41 //    printf("build: l = %d, r = %d, pt[%d].x = %lf, pt[%d].y = %lf
",l,r,rt,pt[rt].x,rt,pt[rt].y);
42     if(l==r)    return;
43     int m=(l+r)>>1;
44     build(lson);
45     build(rson);
46 }
47 void update(int L,int R,int delta,int l,int r,int rt){
48     if(L<=l-1&&r<=R){
49         double rad=getrad(delta);
50         Rotate(pt[rt].x,pt[rt].y,rad);
51         rd[rt]+=delta;
52 //        printf("l = %d, r = %d, pt[%d].x = %lf,pt[%d].y = %lf
",l,r,rt,pt[rt].x,rt,pt[rt].y);
53         return;
54     }
55     if(l==r)    return;
56     pushdown(rt);
57     int m=(l+r)>>1;
58     if(L<=m)    update(L,R,delta,lson);
59     if(m<R)     update(L,R,delta,rson);
60     pushup(rt);
61 }
62 int main(){
63 
64     while(scanf("%d%d",&n,&c)==2){
65         int s,a;
66         for(int i=1;i<=n;i++){
67             scanf("%d",&len[i]);
68             totlen[i]=totlen[i-1]+len[i];
69         }
70         build(1,n,1);                  //_______________________
71         for(int i=0;i<=n;i++)   degree[i]=0;
72         while(c--){
73             scanf("%d%d",&s,&a);
74             a-=180;
75             int delta=a-degree[s];
76             degree[s]=a;
77             update(s,n,delta,1,n,1);
78             printf("%.2lf %.2lf
",pt[1].x,pt[1].y);
79         }
80         printf("
");
81     }
82     return 0;
83 }
View Code
“这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
原文地址:https://www.cnblogs.com/Blogggggg/p/7152996.html