https://www.nowcoder.com/acm/contest/160/D
其实就是通过sin(a+b)=sinacosb+sinbcosa cos(a+b)=cosacosb-sinasinb使操作满足区间加法 纸上一写公式就明白了
但是要注意这个题卡常数 因为sin和cos函数是有一定时间复杂度的 姿势写的不好会T
不知不觉 离去年暑假纳新集训已经过去了一年 正规赛也被队友拖着划水打了几场 成绩都不理想 总是在赛场上因为各种原因GG 说一千道一万 菜是原罪
ACM生涯即将终结 有些遗憾 恨起步太晚 有些迷惘 不知结局喜悲 梦想遥不可及 托遗响于悲风
using namespace std;
struct node
{
int l;
int r;
double laz;
double s;
double c;
};
node tree[800010];
int n,q;
inline void pushup(int cur)
{
tree[cur].s=tree[2*cur].s+tree[2*cur+1].s;
tree[cur].c=tree[2*cur].c+tree[2*cur+1].c;
}
inline void pushdown(int cur)
{
double ts,tc,ls,lc;
if(fabs(tree[cur].laz)>eps)
{
ls=sin(tree[cur].laz),lc=cos(tree[cur].laz);
ts=tree[2*cur].s,tc=tree[2*cur].c;
tree[2*cur].s=lc*ts+ls*tc;
tree[2*cur].c=lc*tc-ls*ts;
tree[2*cur].laz+=tree[cur].laz;
ts=tree[2*cur+1].s,tc=tree[2*cur+1].c;
tree[2*cur+1].s=lc*ts+ls*tc;
tree[2*cur+1].c=lc*tc-ls*ts;
tree[2*cur+1].laz+=tree[cur].laz;
tree[cur].laz=0.0;
}
}
void build(int l,int r,int cur)
{
double val;
int m;
tree[cur].l=l;
tree[cur].r=r;
tree[cur].laz=0.0;
tree[cur].s=0.0;
tree[cur].c=1.0;
if(l==r)
{
scanf("%lf",&val);
tree[cur].s=sin(val);
tree[cur].c=cos(val);
return;
}
m=(l+r)/2;
build(l,m,2*cur);
build(m+1,r,2*cur+1);
pushup(cur);
}
inline void update(int pl,int pr,double val,int cur)
{
double ts,tc,ls,lc;
if(pl<=tree[cur].l&&tree[cur].r<=pr)
{
ls=sin(val),lc=cos(val);
ts=tree[cur].s,tc=tree[cur].c;
tree[cur].s=lc*ts+ls*tc;
tree[cur].c=lc*tc-ls*ts;
tree[cur].laz+=val;
return;
}
pushdown(cur);
if(pl<=tree[2*cur].r) update(pl,pr,val,2*cur);
if(pr>=tree[2*cur+1].l) update(pl,pr,val,2*cur+1);
pushup(cur);
}
inline double query(int pl,int pr,int cur)
{
if(pl<=tree[cur].l&&tree[cur].r<=pr) return tree[cur].s;
pushdown(cur);
double res=0.0;
if(pl<=tree[2*cur].r) res+=query(pl,pr,2*cur);
if(pr>=tree[2*cur+1].l) res+=query(pl,pr,2*cur+1);
return res;
}
int main()
{
double val;
int op,l,r;
scanf("%d",&n);
build(1,n,1);
scanf("%d",&q);
while(q--)
{
scanf("%d",&op);
if(op==1)
{
scanf("%d%d%lf",&l,&r,&val);
update(l,r,val,1);
}
else
{
scanf("%d%d",&l,&r);
printf("%.1f\n",query(l,r,1));
}
}
return 0;
}