我是使用的和差角做的区间维护。不知道为什么过不了。我觉得可能问题在区间修改或者pushdown的地方。感谢您的帮助。
#include <bits/stdc++.h>
#define ls u<<1
#define rs u<<1|1
#define ll long long
using namespace std;
const int N = 2e5 + 5;
int n, q;
double a[N];
struct Segm{
int l, r;
double sin_sum;
double cos_sum;
ll tag;
Segm() { tag = 0.0; }
} tree[N * 4];
const double eps = 1e-8;
inline void pushup(int u)
{
tree[u].sin_sum = tree[ls].sin_sum + tree[rs].sin_sum;
tree[u].cos_sum = tree[ls].cos_sum + tree[rs].cos_sum;
}
inline void pushdown(int u)
{
if (fabs(tree[u].tag) > eps) {
// cout<<1<<endl;
double cv = cos(tree[u].tag);
double sv = sin(tree[u].tag);
double cs, ss;
cs = tree[ls].cos_sum;
ss = tree[ls].sin_sum;
tree[ls].sin_sum = cv * ss + sv * cs;
tree[ls].cos_sum = cv * cs + sv * ss;
cs = tree[rs].cos_sum;
ss = tree[rs].sin_sum;
tree[rs].sin_sum = cv * ss + sv * cs;
tree[rs].cos_sum = cv * cs + sv * ss;
tree[ls].tag += tree[u].tag;
tree[rs].tag += tree[u].tag;
tree[u].tag = 0.0;
}
}
void build(int u, int l, int r)
{
tree[u].l = l, tree[u].r = r;
if (l == r) {
tree[u].sin_sum = sin(a[l]);
tree[u].cos_sum = cos(a[l]);
return;
}
int mid = l + r >> 1;
build(ls, l, mid);
build(rs, mid + 1, r);
pushup(u);
}
void modify(int u, int l, int r, double val)
{
if (tree[u].l > r || tree[u].r < l) {
return;
}
if (l <= tree[u].l && tree[u].r <= r) {
double ss = tree[u].sin_sum, cs = tree[u].cos_sum;
double sv = sin(val), cv = cos(val);
tree[u].sin_sum = cv * ss + sv * cs;
tree[u].cos_sum = cv * cs + sv * ss;
tree[u].tag += val;
return;
}
pushdown(u);
modify(ls, l, r, val);
modify(rs, l, r, val);
pushup(u);
}
double query(int u, int l, int r)
{
if (tree[u].l > r || tree[u].r < l) {
return 0.0;
}
if (l <= tree[u].l && tree[u].r <= r) {
return tree[u].sin_sum;
}
pushdown(u);
return query(ls, l, r) + query(rs, l, r);
}
void prt(int u, int l, int r)
{
if (l == r) {cout<<(tree[u].sin_sum)<< " ";return;}
int mid =l+r>>1;
prt(ls,l,mid);prt(rs,mid+1,r);
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%lf", &a[i]);
}
build(1, 1, n);
scanf("%d", &q);
double v;
for (int i = 1, op, x, y; i <= q; i++) {
// prt(1,1,n);
// cout<<endl;
scanf("%d%d%d", &op, &x, &y);
if (op == 1) {
scanf("%lf", &v);
modify(1, x, y, v);
} else {
printf("%.1lf\n", query(1, x, y));
}
}
return 0;
}