POJ 2991 Crane
题意:给定一个垂直的挖掘机臂。有n段,如今每次操作能够旋转一个位置,把[s, s + 1]专程a度,每次旋转后要输出第n个位置的坐标
思路:线段树。把每一段当成一个向量,这样每一段的坐标就等于前几段的坐标和,然后每次旋转的时候,相当于把当前到最后位置所有加上一个角度,这样就须要区间改动了。然后每次还须要查询s,和s + 1当前的角度,所以须要单点查询,这样用线段树去维护就可以
代码:
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int N = 10005; const double PI = acos(-1.0); #define lson(x) ((x<<1)+1) #define rson(x) ((x<<1)+2) int n, m; double COS[721], SIN[721]; struct Node { int l, r, lazy, R; double x, y; void gao(int ang) { R = (R + ang) % 360; lazy = (lazy + ang) % 360; double tmpx = x, tmpy = y; x = COS[ang + 360] * tmpx - SIN[ang + 360] * tmpy; y = SIN[ang + 360] * tmpx + COS[ang + 360] * tmpy; } } node[N * 4]; void pushup(int x) { node[x].x = node[lson(x)].x + node[rson(x)].x; node[x].y = node[lson(x)].y + node[rson(x)].y; } void pushdown(int x) { if (node[x].lazy) { node[lson(x)].gao(node[x].lazy); node[rson(x)].gao(node[x].lazy); node[x].lazy = 0; } } void build(int l, int r, int x = 0) { node[x].l = l; node[x].r = r; node[x].lazy = node[x].R = 0; if (l == r) { double tmp; scanf("%lf", &tmp); node[x].x = 0.0; node[x].y = tmp; return; } int mid = (l + r) / 2; build(l, mid, lson(x)); build(mid + 1, r, rson(x)); pushup(x); } void add(int l, int r, int v, int x = 0) { if (node[x].l >= l && node[x].r <= r) { node[x].gao(v); return; } int mid = (node[x].l + node[x].r) / 2; pushdown(x); if (l <= mid) add(l, r, v, lson(x)); if (r > mid) add(l, r, v, rson(x)); pushup(x); } int query(int v, int x = 0) { if (node[x].l == node[x].r) return node[x].R; int mid = (node[x].l + node[x].r) / 2; int ans = 0; pushdown(x); if (v <= mid) ans += query(v, lson(x)); if (v > mid) ans += query(v, rson(x)); pushup(x); return ans; } int main() { int bo = 0; for (int i = -360; i <= 360; i++) { COS[i + 360] = cos(i / 180.0 * PI); SIN[i + 360] = sin(i / 180.0 * PI); } while (~scanf("%d%d", &n, &m)) { if (bo) printf(" "); else bo = 1; build(1, n); int s, a; while (m--) { scanf("%d%d", &s, &a); int a1 = query(s); int a2 = query(s + 1); int ang = ((a1 - a2 + a + 180) % 360 + 360) % 360; add(s + 1, n, ang); printf("%.2lf %.2lf ", node[0].x, node[0].y); } } return 0; }