intquery(int x, int y, int p = 1) { node& par = seg[p]; if (x <= par.l && par.r <= y) return par.sum; // 对应操作1 int sum = 0; int mid = (par.l + par.r) / 2; if (mid >= y) sum += query(x, y, p * 2); // 对应操作2 if (mid < x) sum += query(x, y, p * 2 + 1); // 对应操作3 return sum; }
voidbuild(int l, int r, int p = 1) { node& par = seg[p]; par.l = l, par.r = r; if (l == r) { par.val = par.prel = par.prer = par.sum = a[l]; return; } int mid = (l + r) / 2; build(l, mid, p * 2); build(mid + 1, r, p * 2 + 1); pushup(par, seg[p * 2], seg[p * 2 + 1]); }
voidmodify(int x, int val, int p = 1) { node& par = seg[p]; if (par.l == par.r) { par.val = par.prel = par.prer = par.sum = val; return; } int mid = (par.l + par.r) / 2; if (x <= mid) modify(x, val, p * 2); else modify(x, val, p * 2 + 1); pushup(par, seg[p * 2], seg[p * 2 + 1]); }
node query(int x, int y, int p = 1) { node& par = seg[p]; if (x == par.l && y == par.r) return par; int mid = (par.l + par.r) / 2; if (mid >= y) returnquery(x, y, p * 2); if (mid < x) returnquery(x, y, p * 2 + 1); node res; pushup(res, query(x, mid, p * 2), query(mid + 1, y, p * 2 + 1)); return res; }
intmain() { int n, q, op, x, y; scanf("%d", &n); for (int i = 1; i <= n; ++i) scanf("%lld", &a[i]); build(1, n); for (scanf("%d", &q); q--;) { scanf("%d%d%d", &op, &x, &y); if (op) printf("%lld\n", query(x, y).val); else modify(x, y); } }
structnode { int l, r; double x, y, ang; } seg[maxn * 4];
double prv[maxn], len[maxn];
voidbuild(int l, int r, int p = 0) { node& par = seg[p]; par.l = l, par.r = r, par.x = par.ang = 0.0; if (r - l == 1) { par.y = len[l]; return; } int mid = (l + r) / 2; build(l, mid, chl); build(mid, r, chr); // 默认方向是朝上,只需更新纵坐标 par.y = seg[chl].y + seg[chr].y; }
voidmodify(int pos, double delta, int p = 0) { node& par = seg[p]; if (pos <= par.l || pos >= par.r) return; // 若要旋转的位置是该节点区间的端点,甚至不在节点区间内,则没有任何影响 modify(pos, delta, chl); modify(pos, delta, chr); if (pos <= (par.l + par.r) / 2) par.ang += delta; // 若右子节点没有被更新,需要将其向量旋转 double s = sin(par.ang), c = cos(par.ang); // 将左右子节点的向量拼接,更新本节点 par.x = seg[chl].x + (c * seg[chr].x - s * seg[chr].y); par.y = seg[chl].y + (s * seg[chr].x + c * seg[chr].y); }
intmain() { int m, n, cnt = 0; while (scanf("%d%d", &m, &n) != EOF) { if (cnt++) puts(""); for (int i = 1; i != m; ++i) prv[i] = pi; // 初始方向为上方 for (int i = 0; i != m; ++i) scanf("%lf", &len[i]); build(0, m); for (int pos, deg; n--;) { scanf("%d%d", &pos, °); // 利用prv数组,算出角度的变化值,单位是弧度 double rad = (double)deg / 180.0 * pi; modify(pos, rad - prv[pos]); prv[pos] = rad; printf("%.2f %.2f\n", seg[0].x, seg[0].y); } } }