POJ 2991 Crane
二次联通门 : POJ 2991 Crane
/* POJ 2991 Crane 线段树维护向量 对于每次修改操作 修改x的角度 就是修改x~N区间的所有向量 打个标记记录角度 当前向量的计算式子为 res为度数 x = tree[now].x * cos (res) - tree[now].y * sin (res); y = tree[now].x * sin (res) + tree[now].y * cos (res); 注意弧度制与角度值的互换 注意还要记录一下上次该向量的角度, 即angle[i] 每次修改的角度就是x - angle[pos] x是给定的角, pos是修改的位置 查询的话就是第一个点的向量。。。 MMP竟然有负角。。。 我的读入优化没判负数导致WA了半天。。。 */ #include <cstdio> #include <cmath> #define Max 1000001 inline void read (int &now) { now = 0; register char word = getchar (); bool temp = false; while (word < '0' || word > '9') { if (word == '-') temp = true; word = getchar (); } while (word >= '0' && word <= '9') { now = now * 10 + word - '0'; word = getchar (); } if (temp) now = -now; } int N, M; double angle[Max]; class Segment_Tree_Type { private : struct Segment_Tree_Date { int l; int r; int Mid; double x; double y; double Flandre; } tree[Max]; inline void Rotate (int now, int angle) { double res = (double)angle * acos (-1.0) / 180.0; double x = tree[now].x * cos (res) - tree[now].y * sin (res); double y = tree[now].x * sin (res) + tree[now].y * cos (res); tree[now].x = x; tree[now].y = y; } public : void Build (int l, int r, int now) { tree[now].l = l; tree[now].r = r; tree[now].Flandre = 0; if (l == r) { scanf ("%lf", &tree[now].y); tree[now].x = 0; tree[now].Flandre = 0; return ; } tree[now].Mid = l + r >> 1; Build (l, tree[now].Mid, now << 1); Build (tree[now].Mid + 1, r, now << 1 | 1); tree[now].x = tree[now << 1].x + tree[now << 1 | 1].x; tree[now].y = tree[now << 1].y + tree[now << 1 | 1].y; } void Change_section (int l, int r, int now, int to) { if (tree[now].l == l && tree[now].r == r) { tree[now].Flandre += to; Rotate (now, to); return ; } if (tree[now].Flandre) { tree[now << 1].Flandre += tree[now].Flandre; tree[now << 1 | 1].Flandre += tree[now].Flandre; Rotate ((now << 1), tree[now].Flandre); Rotate ((now << 1 | 1), tree[now].Flandre); tree[now].Flandre = 0; } if (r <= tree[now].Mid) Change_section (l, r, now << 1, to); else if (l > tree[now].Mid) Change_section (l, r, now << 1 |1, to); else { Change_section (l, tree[now].Mid, now << 1, to); Change_section (tree[now].Mid + 1, r, now << 1 | 1, to); } tree[now].x = tree[now << 1].x + tree[now << 1 | 1].x; tree[now].y = tree[now << 1].y + tree[now << 1 | 1].y; } inline double Query_x () { return tree[1].x; } inline double Query_y () { return tree[1].y; } void Prepare () { for (int i = 1; i <= Max; i++) angle[i] = 180.0; } }; Segment_Tree_Type Tree; int main (int argc, char *argv[]) { int x, y; for (; scanf ("%d%d", &N, &M) == 2; ) { Tree.Build (1, N, 1); Tree.Prepare (); for (; M--; ) { read (x); read (y); Tree.Change_section (x + 1, N, 1, y - angle[x]); printf ("%.2lf %.2lf\n", Tree.Query_x (), Tree.Query_y ()); angle[x] = (double)y; } } return 0; }
myj 吊打我Orz,xxy 捆起来打我Orz,myl 文化课上天Orz, lrh 姿势水平敲高Orz, hkd 特别胖Orz%%%,cys 智商感人Orz,syl zz专业Orz,我没有学上, 我们未来一片光明