思路:
线段树每个节点维护第一条线段起点指向最后一条线段终点的向量,于是每一个操作都是一次区间更新。使用成段更新的线段树即可。
实现:
1 #include <cstdio> 2 #include <iostream> 3 #include <cmath> 4 #include <cstring> 5 6 using namespace std; 7 8 const int MAXN = 10005; 9 const double PI = acos(-1.0); 10 11 int a[MAXN], d[MAXN], n, c; 12 struct node 13 { 14 double x, y; 15 int lazy; 16 }; 17 node tree[MAXN << 2]; 18 double trans(int d) { return (double)d * PI / 180.0; } 19 void rotate(double & x, double & y, int dx) 20 { 21 double tx = x * cos(trans(dx)) - y * sin(trans(dx)); 22 double ty = y * cos(trans(dx)) + x * sin(trans(dx)); 23 x = tx; y = ty; 24 } 25 void pushdown(int num) 26 { 27 if (!tree[num].lazy) return; 28 int tmp = tree[num].lazy; 29 rotate(tree[num << 1].x, tree[num << 1].y, tmp); 30 rotate(tree[num << 1 | 1].x, tree[num << 1 | 1].y, tmp); 31 tree[num << 1].lazy += tmp; 32 tree[num << 1 | 1].lazy += tmp; 33 tree[num].lazy = 0; 34 } 35 void pushup(int num) 36 { 37 tree[num].x = tree[num << 1].x + tree[num << 1 | 1].x; 38 tree[num].y = tree[num << 1].y + tree[num << 1 | 1].y; 39 } 40 void build(int num, int l, int r) 41 { 42 if (l == r) { tree[num].y = a[r]; return; } 43 int m = l + r >> 1; 44 build(num << 1, l, m); 45 build(num << 1 | 1, m + 1, r); 46 pushup(num); 47 } 48 void update(int num, int l, int r, int x, int y, int dx) 49 { 50 if (x <= l && y >= r) 51 { 52 rotate(tree[num].x, tree[num].y, dx); 53 tree[num].lazy += dx; 54 return; 55 } 56 int m = l + r >> 1; 57 pushdown(num); 58 if (x <= m) update(num << 1, l, m, x, y, dx); 59 if (y >= m + 1) update(num << 1 | 1, m + 1, r, x, y, dx); 60 pushup(num); 61 } 62 63 int main() 64 { 65 while (scanf("%d %d", &n, &c) != EOF) 66 { 67 for (int i = 1; i <= n * 4; i++) { tree[i].x = tree[i].y = 0; tree[i].lazy = 0; } 68 for (int i = 1; i <= n; i++) scanf("%d", &a[i]); 69 for (int i = 1; i < n; i++) d[i] = 180; 70 build(1, 1, n); 71 int x, y; 72 for (int i = 0; i < c; i++) 73 { 74 scanf("%d %d", &x, &y); 75 int dx = y - d[x]; 76 d[x] = y; 77 update(1, 1, n, x + 1, n, dx); 78 printf("%.2f %.2f\n", tree[1].x, tree[1].y); 79 } 80 puts(""); 81 } 82 return 0; 83 }