zoukankan      html  css  js  c++  java
  • SCUT

    https://scut.online/p/337

    这个东西是个阶梯状的。那么可以考虑存两棵树,一棵树是阶梯的,另一棵树的平的,随便一减就是需要的阶梯。

    优化之后貌似速度比树状数组还惊人。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    inline int read() {
        int x=0;
        int f=0;
        char c;
        do {
            c=getchar();
            if(c=='-')
                f=1;
        } while(c<'0'||c>'9');
        do {
            x=(x<<3)+(x<<1)+c-'0';
            c=getchar();
        } while(c>='0'&&c<='9');
        return f?-x:x;
    }
    
    inline void _write(int x) {
        if(x>9)
            _write(x/10);
        putchar(x%10+'0');
    }
    
    inline void write(int x) {
        if(x<0) {
            putchar('-');
            x=-x;
        }
        _write(x);
        putchar('
    ');
    }
    
    void TestCase(int ti);
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in","r",stdin);
        //freopen("Yinku.out","w",stdout);
    #endif // Yinku
        int T=1;
        for(int ti=1; ti<=T; ti++)
            TestCase(ti);
    }
    
    /*---  ---*/
    
    const int MAXM=100000;
    int a[MAXM+5];
    int st[(MAXM<<2)+5];
    int st2[(MAXM<<2)+5];
    
    const int mod=1000000007;
    
    inline int add(const int &a,const int &b){
        int res=a+b;
        return res>=mod?res-mod:res;
    }
    
    inline int sub(const int &a,const int &b){
        int res=a-b;
        return res<0?res+mod:res;
    }
    
    inline int mul(const int &a,const int &b){
        ll res=1ll*a*b;
        return res>=mod?res%mod:res;
    }
    
    inline void push_up(int o) {
        st[o]=add(st[o<<1],st[o<<1|1]);
        st2[o]=add(st2[o<<1],st2[o<<1|1]);
    }
    
    void build(int o,int l,int r) {
        if(l==r){
            st[o]=a[l];
            st2[o]=mul(l,a[l]);
        }
        else {
            int m=(l+r)>>1;
            build(o<<1,l,m);
            build(o<<1|1,m+1,r);
            push_up(o);
        }
    }
    
    void update(int o,int l,int r,int x,int v) {
        if(l==r) {
            st[o]=v;
            st2[o]=mul(x,v);
            return;
        } else {
            int m=(l+r)>>1;
            if(x<=m)
                update(o<<1,l,m,x,v);
            else if(x>=m+1)
                update(o<<1|1,m+1,r,x,v);
            push_up(o);
        }
    }
    
    int query1(int o,int l,int r,int a,int b) {
        if(a<=l&&r<=b) {
            return st[o];
        } else {
            int m=(l+r)>>1;
            int ans=0;
            if(a<=m)
                ans=query1(o<<1,l,m,a,b);
            if(b>=m+1)
                ans=add(ans,query1(o<<1|1,m+1,r,a,b));
            return ans;
        }
    }
    
    int query2(int o,int l,int r,int a,int b) {
        if(a<=l&&r<=b) {
            return st2[o];
        } else {
            int m=(l+r)>>1;
            int ans=0;
            if(a<=m)
                ans=query2(o<<1,l,m,a,b);
            if(b>=m+1)
                ans=add(ans,query2(o<<1|1,m+1,r,a,b));
            return ans;
        }
    }
    
    inline void TestCase(int ti) {
        int n,m;
        while(~scanf("%d",&n)) {
            for(int i=1; i<=n; i++)
                scanf("%d",&a[i]);
            build(1,1,n);
            scanf("%d",&m);
            for(int i=1; i<=m; i++) {
                char a[2];
                int b,c;
                scanf("%s%d%d",a,&b,&c);
                if(a[0]=='Q') {
                    printf("%d
    ",sub(query2(1,1,n,b,c),mul(b-1,query1(1,1,n,b,c))));
                } else {
                    update(1,1,n,b,c);
                }
            }
        }
    }
    

    这个树状数组就不太好懂了,不过空间是线段树的1/4,速度是其两倍。
    单点改值就把差值update上去就可以了。然后记得把原始值也顺手改了。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    inline int read() {
        int x=0;
        int f=0;
        char c;
        do {
            c=getchar();
            if(c=='-')
                f=1;
        } while(c<'0'||c>'9');
        do {
            x=(x<<3)+(x<<1)+c-'0';
            c=getchar();
        } while(c>='0'&&c<='9');
        return f?-x:x;
    }
    
    inline void _write(int x) {
        if(x>9)
            _write(x/10);
        putchar(x%10+'0');
    }
    
    inline void write(int x) {
        if(x<0) {
            putchar('-');
            x=-x;
        }
        _write(x);
        putchar('
    ');
    }
    
    void TestCase(int ti);
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in","r",stdin);
        //freopen("Yinku.out","w",stdout);
    #endif // Yinku
        int T=1;
        for(int ti=1; ti<=T; ti++)
            TestCase(ti);
    }
    
    /*---  ---*/
    
    const int MAXM=100000;
    int a[MAXM+5];
    int bit[MAXM+5];
    int bit2[MAXM+5];
    
    int n;
    
    const int mod=1000000007;
    
    inline int add(const int &a,const int &b) {
        int res=a+b;
        return res>=mod?res-mod:res;
    }
    
    inline int sub(const int &a,const int &b) {
        int res=a-b;
        return res<0?res+mod:res;
    }
    
    inline int mul(const int &a,const int &b) {
        ll res=1ll*a*b;
        return res>=mod?res%mod:res;
    }
    
    inline int sum(int x,int bit[]) {
        int res=0;
        while(x) {
            res=add(res,bit[x]);
            x-=x&-x;
        }
        return res;
    }
    
    inline void update(int x,int v,int bit[]) {
        while(x<=n) {
            bit[x]=add(bit[x],v);
            x+=x&-x;
        }
    }
    
    inline int range_sum(int x,int y,int bit[]) {
        return sub(sum(y,bit),sum(x-1,bit));
    }
    
    inline void TestCase(int ti) {
        int m;
        while(~scanf("%d",&n)) {
            memset(bit,0,sizeof(bit));
            memset(bit2,0,sizeof(bit2));
            for(int i=1; i<=n; i++) {
                scanf("%d",&a[i]);
                update(i,a[i],bit);
                update(i,mul(i,a[i]),bit2);
            }
            scanf("%d",&m);
            for(int i=1; i<=m; i++) {
                char s[2];
                int b,c;
                scanf("%s%d%d",s,&b,&c);
                if(s[0]=='Q') {
                    printf("%d
    ",sub(range_sum(b,c,bit2),mul(b-1,range_sum(b,c,bit))));
                } else {
                    int delta=sub(c,a[b]);
                    update(b,delta,bit);
                    update(b,mul(b,delta),bit2);
                    a[b]=c;
                }
            }
        }
    }
    
  • 相关阅读:
    项目管理实践【三】每日构建【Daily Build Using CruiseControl.NET and MSBuild】
    项目管理实践教程二、源代码控制【Source Control Using VisualSVN Server and TortoiseSVN】
    javascript 容易忽略或者误用的七个基础知识点
    未来的路还很长
    Nodejs
    CSS浏览器兼容性相关
    HTML5
    一些正则
    Sublime 使用
    Array.prototype.slice.call(arguments,1)
  • 原文地址:https://www.cnblogs.com/Yinku/p/11039894.html
Copyright © 2011-2022 走看看