蒟蒻调了两三个小时了,还是没调出来
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=400005;
int n,m,opt,l,r;
double a[N];
int ls(int x)
{
return x<<1;
}
int rs(int x)
{
return x<<1|1;
}
struct node{
double cosx,sinx;
double tag;
}c[N];
void pushup(int rt)
{
c[rt].sinx=c[ls(rt)].sinx+c[rs(rt)].sinx;
c[rt].cosx=c[ls(rt)].cosx+c[rs(rt)].cosx;
}
void upd(int rt,int k)
{
if(k==0) return;
double xx=sin(k),yy=cos(k);
double sx,sy;
sx=c[rt].sinx*yy+c[rt].cosx*xx;
sy=c[rt].cosx*yy-c[rt].sinx*xx;
c[rt].sinx=sx;
c[rt].cosx=sy;
c[rt].tag+=k;
}
void build(int l,int r,int rt)
{
if(l==r)
{
c[rt].sinx=sin(a[l]);
c[rt].cosx=cos(a[l]);
return;
}
c[rt].tag=0;
int mid=(l+r)>>1;
build(l,mid,ls(rt));
build(mid+1,r,rs(rt));
pushup(rt);
}
void pushdown(int rt)
{
upd(ls(rt),c[rt].tag);
upd(rs(rt),c[rt].tag);
c[rt].tag=0;
}
double query(int l,int r,int nl,int nr,int rt)
{
double res=0;
if(nl<=l&&r<=nr)
{
res=c[rt].sinx;
return res;
}
pushdown(rt);
int mid=(l+r)>>1;
if(nl<=mid) res+=query(l,mid,nl,nr,ls(rt));
if(mid<nr) res+=query(mid+1,r,nl,nr,rs(rt));
return res;
}
void update(int l,int r,int nl,int nr,int rt,int k)
{
if(nl<=l&&r<=nr)
{
upd(rt,k);
return;
}
pushdown(rt);
int mid=(l+r)>>1;
if(nl<=mid) update(l,mid,nl,nr,ls(rt),k);
if(mid<nr) update(mid+1,r,nl,nr,rs(rt),k);
pushup(rt);
}
signed main(){
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
build(1,n,1);
cin>>m;
for(int i=1;i<=m;i++)
{
cin>>opt>>l>>r;
if(opt==1)
{
double k;
cin>>k;
update(1,n,l,r,1,k);
}
if(opt==2)
{
cout<<fixed<<showpoint<<setprecision(1)<<query(1,n,l,r,1)<<endl;
}
}
return 0;
}