Loading... [Link](https://www.luogu.com.cn/problem/P6327) ## 前置知识 这个题还是要先学会和角公式(~~有的什么毒瘤复数的做法太无聊了~~) $$ \sin(\alpha + \beta) = \sin(\alpha)\cos(\beta) + \cos(\alpha)\sin(\beta) $$ $$ \cos(\alpha + \beta) = \cos(\alpha)\cos(\beta) - \sin(\alpha)\sin(\beta) $$ ## Sol 有了上面的公式,你应该就会做这个题了. 加入现在要给 $[l,r]$ 内的所有角加上一个 $\alpha$ 角 那么 $$ \sum_{i=l}^{r} \sin(a_i + \alpha) = \sum_{i=l}^{r} \sin(a_i) \times \cos(\alpha) + \sum_{i= l}^{r} \cos(a_i) \times \sin(\alpha) $$ 那么需要维护区间 $\sin$ 和 $\cos$ 的和 $$ \sum_{i=l}^{r} \cos(a_i + \alpha) = \sum_{i=l}^{r} \cos(a_i) \times \cos(\alpha) - \sum_{i= l}^{r} \sin(a_i) \times \sin(\alpha) $$ 也许到这里你就会了. 还要注意的地方是,每次更新 $\sin$ 和 $\cos$ 的时候要先记录一下没更新前的值,再更新.如果你这么做的话 ```tree[lson(p)].sine = cos(tree[p].tag) * tree[lson(p)].sine + sin(tree[p].tag) * tree[lson(p)].cosine;``` ``` tree[lson(p)].cosine = tree[lson(p)].cosine * cos(tree[p].tag) - tree[lson(p)].sine * sin(tree[p].tag);``` 就会跟我一样~~sb~~ 还有要开`long long` ## Code ```cpp #include <bits/stdc++.h> using namespace std; #define int long long const int SIZE = 3e5 + 5; int n, q; int a[SIZE]; struct node { int l, r, tag; double cosine, sine; } tree[SIZE << 2]; namespace ae86 { const int bufl = 1 << 15; char buf[bufl], *s = buf, *t = buf; inline int fetch() { if (s == t) { t = (s = buf) + fread(buf, 1, bufl, stdin); if (s == t) return EOF; } return *s++; } inline int read() { int a = 0, b = 1, c = fetch(); while (!isdigit(c))b ^= c == '-', c = fetch(); while (isdigit(c)) a = a * 10 + c - 48, c = fetch(); return b ? a : -a; } } using ae86::read; #define lson(p) p << 1 #define rson(p) p << 1 | 1 inline void pushUp(int p) { tree[p].cosine = tree[lson(p)].cosine + tree[rson(p)].cosine; tree[p].sine = tree[lson(p)].sine + tree[rson(p)].sine; } inline void pushDown(int p) { if (tree[p].tag != 0.00) { double lsine = tree[lson(p)].sine, rsine = tree[rson(p)].sine; double lcos = tree[lson(p)].cosine, rcos = tree[rson(p)].cosine; tree[lson(p)].sine = cos(tree[p].tag) * lsine + sin(tree[p].tag) * lcos; tree[lson(p)].cosine = lcos * cos(tree[p].tag) - lsine * sin(tree[p].tag); tree[rson(p)].sine = cos(tree[p].tag) * rsine + sin(tree[p].tag) * rcos; tree[rson(p)].cosine = rcos * cos(tree[p].tag) - rsine * sin(tree[p].tag); tree[lson(p)].tag += tree[p].tag, tree[rson(p)].tag += tree[p].tag, tree[p].tag = 0; } } inline void build(int p, int l, int r) { tree[p].l = l, tree[p].r = r; if (l == r) { tree[p].cosine = cos(a[l]), tree[p].sine = sin(a[l]); return; } int mid = (l + r) >> 1; build(lson(p), l, mid); build(rson(p), mid + 1, r); pushUp(p); } inline void modify(int p, int l, int r, int v) { if (l <= tree[p].l && tree[p].r <= r) { double si = tree[p].sine, co = tree[p].cosine; tree[p].sine = cos(v) * si + sin(v) * co; tree[p].cosine = co * cos(v) - si * sin(v); tree[p].tag += v; return; } pushDown(p); int mid = (tree[p].l + tree[p].r) >> 1; if (l <= mid) modify(lson(p), l, r, v); if (r > mid) modify(rson(p), l, r, v); pushUp(p); } inline double query(int p, int l, int r) { if (l <= tree[p].l && tree[p].r <= r) { return tree[p].sine; } pushDown(p); int mid = (tree[p].l + tree[p].r) >> 1; double ans = 0.00; if (l <= mid) ans += query(lson(p), l, r); if (r > mid) ans += query(rson(p), l, r); return ans; } signed main() { n = read(); for (int i = 1; i <= n; ++ i) { a[i] = read(); } build(1, 1, n); q = read(); int opt, l, r, v; while (q --) { opt = read(); if (opt == 1) { l = read(), r = read(), v = read(); modify(1, l, r, v); } if (opt == 2) { l = read(), r = read(); printf("%.1lf\n", query(1, l, r)); } } return 0; } ``` 最后修改:2021 年 09 月 04 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏