zoukankan      html  css  js  c++  java
  • [Ynoi2012]NOIP2015洋溢着希望

    维护序列,支持区间加,区间求 (sum sin(a_i))

    Solution

    考虑到 (sin(a+x)=sin(a)cos(x)+cos(a)sin(x))(cos) 类似

    于是我们可以对每个结点维护 (sum a,sum sin, sum cos) 以及懒标记 (tag)

    #include <bits/stdc++.h>
    #include <unordered_map>
    using namespace std;
    
    #define int long long
    const int N = 1000005;
    
    int n,m,a[N],t1,t2,t3,t4;
    
    double gsin(int t) {
        /*if(mps[t]) return mps[t];
        return mps[t]=sin(t);*/
        return sin(t);
    }
    
    double gcos(int t) {
        /*if(mpc[t]) return mpc[t];
        return mpc[t]=cos(t);*/
        return cos(t);
    }
    
    struct node {
        int a,t;
        double s,c=1;
    } tr[N];
    
    void put(int p,int x) {
        double s,c;
        double gc=gcos(x),gs=gsin(x);
        s=tr[p].s*gc+tr[p].c*gs;
        c=tr[p].c*gc-tr[p].s*gs;
        tr[p].s=s;
        tr[p].c=c;
        tr[p].t+=x;
    }
    
    void pushdown(int p) {
        if(tr[p].t) {
            put(p*2,tr[p].t);
            put(p*2+1,tr[p].t);
            tr[p].t=0;
        }
    }
    
    void pushup(int p) {
        tr[p].a=tr[p*2].a+tr[p*2+1].a;
        tr[p].s=tr[p*2].s+tr[p*2+1].s;
        tr[p].c=tr[p*2].c+tr[p*2+1].c;
    }
    
    void modify(int p,int l,int r,int ql,int qr,int x) {
        if(l>qr||r<ql) return;
        if(l>=ql&&r<=qr) {
            put(p,x);
        }
        else {
            pushdown(p);
            modify(p*2,l,(l+r)/2,ql,qr,x);
            modify(p*2+1,(l+r)/2+1,r,ql,qr,x);
            pushup(p);
        }
    }
    
    double query(int p,int l,int r,int ql,int qr) {
        if(l>qr||r<ql) return 0;
        if(l>=ql&&r<=qr) {
            return tr[p].s;
        }
        else {
            pushdown(p);
            return query(p*2,l,(l+r)/2,ql,qr)+
                query(p*2+1,(l+r)/2+1,r,ql,qr);
        }
    }
    
    void build(int p,int l,int r) {
        if(l==r) {
            put(p,a[l]);
        }
        else {
            build(p*2,l,(l+r)/2);
            build(p*2+1,(l+r)/2+1,r);
            pushup(p);
        }
    }
    
    signed main() {
        ios::sync_with_stdio(false);
        scanf("%lld",&n);
        for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
        build(1,1,n);
        scanf("%lld",&m);
        for(int i=1;i<=m;i++) {
            scanf("%lld%lld%lld",&t1,&t2,&t3);
            if(t1==1) {
                scanf("%lld",&t4);
                modify(1,1,n,t2,t3,t4);
            }
            else {
                printf("%.1lf
    ",query(1,1,n,t2,t3));
            }
        }
    }
    
    
  • 相关阅读:
    多线程、事件驱动与推荐引擎框架选型
    Protobuf协议应用干货
    集群选举算法实现
    基于OpenSSL的HTTPS通信C++实现
    通过UNIX域套接字传递描述符的应用
    我的博客即将入驻“云栖社区”,诚邀技术同仁一同入驻。
    C++反射机制:可变参数模板实现C++反射
    git多个远程仓库
    设计模式—模板方法的C++实现
    Java中的运算符
  • 原文地址:https://www.cnblogs.com/mollnn/p/12563044.html
Copyright © 2011-2022 走看看