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;
}
                










