题意:
维护一个数列,支持两种操作
1.给一个区间所有数加v
2.询问一个区间内所有余弦的和
维护一个余弦和,一个正弦和即可,cosv sinv提出,然后打标记即可~
#include<set>
#include<ctime>
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define RAND() (rand())
using namespace std;
double dc[800005],ds[800005],dcos[800005],dsin[800005];
void Maketree(int k,int l,int r)
{
dc[k]=1;ds[k]=0;
if(l==r)
{
double x;
scanf("%lf",&x);
dsin[k]=sin(x);
dcos[k]=cos(x);
return ;
}
int m=(l+r)>>1;
Maketree(k*2,l,m);
Maketree(k*2+1,m+1,r);
dsin[k]=dsin[k*2]+dsin[k*2+1];
dcos[k]=dcos[k*2]+dcos[k*2+1];
}
inline void Add(int k,double sD,double cD)
{
double Dc=dc[k],Ds=ds[k];
ds[k]=Dc*sD+Ds*cD;
dc[k]=Dc*cD-Ds*sD;
Dc=dcos[k],Ds=dsin[k];
dsin[k]=Dc*sD+Ds*cD;
dcos[k]=Dc*cD-Ds*sD;
}
inline void push_down(int k)
{
Add(k*2,ds[k],dc[k]);
Add(k*2+1,ds[k],dc[k]);
dc[k]=1;ds[k]=0;
}
void Update(int k)
{
dsin[k]=dsin[k*2]+dsin[k*2+1];
dcos[k]=dcos[k*2]+dcos[k*2+1];
}
void Change(int k,int l,int r,int x,int y,double sD,double cD)
{
if(x<=l&&y>=r)
{
Add(k,sD,cD);
return ;
}
push_down(k);
int m=(l+r)>>1;
if (x <= m)
Change(k*2,l,m,x,y,sD,cD);
if( y>m)
Change(k*2+1,m+1,r,x,y,sD,cD);
/*if(x>m)
Change(k*2+1,m+1,r,x,y,D);
else
if(y<=m)
Change(k*2,l,m,x,y,D);
else
{
Change(k*2,l,m,x,m,D);
Change(k*2+1,m+1,r,m+1,y,D);
}*/
Update(k);
}
double Query(int k,int l,int r,int x,int y)
{
if(x<=l&&y>=r)
return dcos[k];
push_down(k);
int m=(l+r)>>1;
double ans=0;
if (x <= m)
ans+=Query(k*2,l,m,x,y);
if( y>m)
ans+=Query(k*2+1,m+1,r,x,y);
/*if(x>m)
ans=Query(k*2+1,m+1,r,x,y);
else
if(y<=m)
ans=Query(k*2,l,m,x,y);
else
ans=Query(k*2,l,m,x,m)+Query(k*2+1,m+1,r,m+1,y);*/
Update(k);
return ans;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
int T;
scanf("%d",&T);
for(int testcase=1;testcase<=T;testcase++)
{
printf("Case #%d:\n",testcase);
int n,m;
scanf("%d%d",&n,&m);
Maketree(1,1,n);
for(int i=1,ch,l,r;i<=m;i++)
{
double c;
scanf("%d",&ch);
if(ch==1)
{
scanf("%d%d%lf",&l,&r,&c);
Change(1,1,n,l,r,sin(c),cos(c));
}
else
{
scanf("%d%d",&l,&r);
printf("%lf\n",Query(1,1,n,l,r));
}
}
}
}