样例,没有过,不知道为什么。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
#include<cstdlib>
#include<iomanip>
#include<map>
#define int long long
#define doub long double
using namespace std;
const int maxn=2e5+7;
inline int lc(int p){
return p<<1;
}
inline int rc(int p){
return p<<1|1;
}
int n;
int a[maxn];
int m;
struct SGT{
struct node{
int tg;
doub sins;
doub coss;
}d[maxn<<2];
void pu(int p){
d[p].sins=d[lc(p)].sins+d[rc(p)].sins;
d[p].coss=d[lc(p)].coss+d[rc(p)].coss;
}
void clc(node p,int v){
p.tg+=v;
doub s=sin(v*1.0);
doub c=cos(v*1.0);
doub ps=p.sins;
doub pc=p.coss;
p.sins=ps*c+pc*s;
p.coss=pc*c-ps*s;
}
void pd(int p){
int t=d[p].tg;
d[p].tg=0;
clc(d[lc(p)],t);
clc(d[rc(p)],t);
}
void build(int p,int l,int r){
if(l==r){
d[p]=(node){0,sin(a[l]),cos(a[l])};
return;
}
int mid=l+r>>1;
build(lc(p),l,mid);
build(rc(p),mid+1,r);
pu(p);
}
void upd(int L,int R,int v,int p,int l,int r){
if(L<=l&&r<=R){
clc(d[p],v);
return;
}
pd(p);
int mid=l+r>>1;
if(L<=mid)upd(L,R,v,lc(p),l,mid);
if(R>mid)upd(L,R,v,rc(p),mid+1,r);
pu(p);
}
doub qry(int L,int R,int p,int l,int r){
if(L<=l&&r<=R)return d[p].sins;
pd(p);
doub ans=0;
int mid=l+r>>1;
if(L<=mid)ans+=qry(L,R,lc(p),l,mid);
if(R>mid)ans+=qry(L,R,rc(p),mid+1,r);
return ans;
}
}T;
signed main(){
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
T.build(1,1,n);
cin>>m;
while(m--){
int op;
cin>>op;
if(op==1){
int l,r,v;
cin>>l>>r>>v;
T.upd(l,r,v,1,1,n);
}
else if(op==2){
int l,r;
cin>>l>>r;
cout<<fixed<<setprecision(1)<<T.qry(l,r,1,1,n)<<endl;
}
}
}