有保存,有LL。
#include<bits/stdc++.h>
#define int long long
#define double long double
using namespace std;
typedef long long LL;
const int N = 4e5 + 10;
int n, m;
LL a[N];
struct node
{
double ssin, scos;
LL tag;
} seg[N * 4];
void update(int id)
{
seg[id].ssin = seg[id * 2].ssin + seg[id * 2 + 1].ssin;
seg[id].scos = seg[id * 2].scos + seg[id * 2 + 1].scos;
}
void build(int id, int l, int r)
{
if (l == r)
{
seg[id].scos = cos(a[l]);
seg[id].ssin = sin(a[l]);
return ;
}
int mid = l + r >> 1;
build(id * 2, l, mid);
build(id * 2 + 1, mid + 1, r);
update(id);
}
void settag(int id, LL t)
{
double p = sin(t), q = cos(t);
double x = seg[id].ssin, y = seg[id].scos;
seg[id].ssin = x * q + y * p;
seg[id].scos = y * q - x * p;
seg[id].tag += t;
}
void pushdown(int id)
{
if (seg[id].tag)
{
settag(id * 2, seg[id].tag);
settag(id * 2 + 1, seg[id].tag);
seg[id].tag = 0;
}
}
void modify(int id, int l, int r, int ql, int qr, LL t)
{
if (ql == l && qr == r)
{
settag(id, t);
return ;
}
pushdown(id);
int mid = l + r >> 1;
if (qr <= mid) modify(id * 2, l, mid, ql, qr, t);
else if (ql > mid) modify(id * 2 + 1, mid + 1, r, ql, qr, t);
else
{
modify(id * 2, l, mid, ql, mid, t);
modify(id * 2 + 1, mid + 1, r, mid + 1, qr, t);
}
update(id);
}
double query(int id, int l, int r, int ql, int qr)
{
if (ql == l && r == qr) return seg[id].ssin;
pushdown(id);
int mid = l + r >> 1;
if (qr <= mid) return query(id * 2, l, mid, ql, qr);
else if (ql > mid) return query(id * 2 + 1, mid + 1, r, ql, qr);
else return query(id * 2, l, mid, ql, mid) + query(id * 2 + 1, mid + 1, r, mid + 1, qr);
}
void solve()
{
cin >> n ;
for (int i = 1; i <= n; i++) cin >> a[i];
build(1, 1, n);
cin >> m;
for (int i = 1; i <= m; i++)
{
int op;
cin >> op;
LL l, r, v;
if (op == 1)
{
cin >> l >> r >> v;
modify(1, 1, n, l, r, v);
} else
{
cin >> l >> r;
cout << query(1, 1, n, l, r) << endl;
}
}
}
signed main()
{
cout << fixed << setprecision(1) << endl;
cin.tie(0);
cout.tie(0);
solve();
return 0;
}