死活调不出来,已经是第n次重构了qwq(不要在意大常熟)
#include <algorithm>
#include <cstring>
#include <iostream>
#include <cstdio>
#include <cctype>
#include <string>
#include <cmath>
#define ll long long
#define ri register int
char buf[1 << 20], *p1, *p2;
//#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 20, stdin), p1 == p2)?EOF: *p1++)
template <typename T> inline void read(T &t) {
ri v = getchar();T f = 1;t = 0;
while (!isdigit(v)) {if (v == '-')f = -1;v = getchar();}
while (isdigit(v)) {t = t * 10 + v - 48;v = getchar();}
t *= f;
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
read(t);read(args...);
}
template <typename T> inline T min(T x,T y) {return x<y?x:y;}
template <typename T> inline T max(T x,T y) {return x>y?x:y;}
const int INF = 0x3f3f3f3f;
const int N = 200010;
struct node {
int l,r,tag;
double sinn,coss;
}tree[N << 2];
int a[N],n,m;
double cosv,sinv;
void pushup(int p) {
tree[p].coss = tree[p << 1].coss + tree[p << 1 | 1].coss;
tree[p].sinn = tree[p << 1].sinn + tree[p << 1 | 1].sinn;
}
void change(int p,double sinx,double cosx) {
double cosa = tree[p].coss,sina = tree[p].sinn;
tree[p].coss = cosa * cosx - sina * sinx;
tree[p].sinn = sina * cosx + cosa * sinx;
return ;
}
void pushdown(int p) {
if (tree[p].tag) {
double cosa = cos(tree[p].tag),sina = sin(tree[p].tag);
change(p << 1,sina,cosa);
change(p << 1 | 1,sina,cosa);
tree[p << 1].tag += tree[p].tag;
tree[p << 1 | 1].tag += tree[p].tag;
tree[p].tag = 0;
}
return ;
}
void build(int p,int l,int r) {
tree[p].l = l,tree[p].r = r;
if (l == r) {
tree[p].coss = cos(a[l]);
tree[p].sinn = sin(a[l]);
return ;
}
int mid = (l + r) >> 1;
build(p << 1,l,mid);
build(p << 1 | 1,mid + 1,r);
pushup(p);
return ;
}
void modify(int p,int l,int r,int x) {
if (tree[p].l >= l && tree[p].r <= r) {
change(p,sinv,cosv);
tree[p].tag += x;return ;
}
pushdown(p);
int mid = (tree[p].l + tree[p].r) >> 1;
if (l <= mid) modify(p << 1,l,r,x);
if (r > mid) modify(p << 1 | 1,l,r,x);
pushup(p);
return ;
}
double query(int p,int l,int r) {
if (tree[p].l >= l && tree[p].r <= r) {
return tree[p].sinn;
}
pushdown(p);
int mid = (tree[p].l + tree[p].r) >> 1;
double ans = 0.0;
if (l <= mid) ans += query(p << 1,l,r);
if (r > mid) ans += query(p << 1 | 1,l,r);
return ans;
}
signed main() {
read(n);
for (int i = 1;i <= n;++i) read(a[i]);
read(m);
build(1,1,n);
while (m--) {
int opt,x,y;read(opt,x,y);
if (opt == 1) {
int v;read(v);
sinv = sin(v),cosv = cos(v);
modify(1,x,y,v);
}
if (opt == 2) {
printf("%.1lf\n",query(1,x,y));
}
}
return 0;
}