RT.玄关
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
const int maxn=2e5+20;
struct seg
{
int the_st[maxn];
double num[4*maxn];
double num2[4*maxn];
long long lazy[4*maxn];
inline int lson(int x){return x<<1;}
inline int rson(int x){return (x<<1)|1;}
void pushup(int now)
{
num[now]=num[lson(now)]+num[rson(now)];
num2[now]=num2[lson(now)]+num2[rson(now)];
}
void build(int now,int l,int r)
{
if(l==r)
{
num[now]=sin(the_st[l]);
num2[now]=cos(the_st[l]);
return;
}
int mid=(l+r)>>1;
build(lson(now),l,mid);
build(rson(now),mid+1,r);
pushup(now);
}
void update(int now,double sinx,double cosx)
{
double sink=num[now],cosk=num2[now];
num[now]=sink*cosx+cosk*sinx;
num2[now]=cosk*cosx-sinx*sink;
}
void push_down(int now)
{
lazy[lson(now)]+=lazy[now];
lazy[rson(now)]+=lazy[now];
int t1=sin(lazy[now]),t2=cos(lazy[now]);
update(lson(now),t1,t2);
update(rson(now),t1,t2);
lazy[now]=0;
}
void change(int now,int l,int r,int ql,int qr,int add)
{
if(ql<=l&&r<=qr)
{
lazy[now]+=add;
update(now,sin(add),cos(add));
return;
}
push_down(now);
int mid=(l+r)>>1;
if(ql<=mid)change(lson(now),l,mid,ql,qr,add);
if(mid<qr)change(rson(now),mid+1,r,ql,qr,add);
pushup(now);
}
double query(int now,int l,int r,int ql,int qr)
{
if(ql<=l&&r<=qr)
{
return num[now];
}
push_down(now);
int mid=(l+r)>>1;
double ans=0;
if(ql<=mid)ans+=query(lson(now),l,mid,ql,qr);
if(mid<qr)ans+=query(rson(now),mid+1,r,ql,qr);
return ans;
}
}seg;
int main()
{
int n,t;
cin>>n;
for(int i=1;i<=n;i++)cin>>seg.the_st[i];
seg.build(1,1,n);cin>>t;
for(int i=1;i<=t;i++)
{
int t1,t2,t3,t4;cin>>t1>>t2>>t3;
if(t1==1){cin>>t4;seg.change(1,1,n,t2,t3,t4);}
else printf("%.1lf\n",seg.query(1,1,n,t2,t3));
}
}