码迷,mamicode.com
首页 > 其他好文 > 详细

SCUT - 337 - 岩殿居蟹 - 线段树

时间:2019-06-17 15:49:50      阅读:117      评论:0      收藏:0      [点我收藏+]

标签:scan   har   mes   线段   utc   turn   testcase   oid   lse   

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('\n');
}

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\n",sub(query2(1,1,n,b,c),mul(b-1,query1(1,1,n,b,c))));
            } else {
                update(1,1,n,b,c);
            }
        }
    }
}

SCUT - 337 - 岩殿居蟹 - 线段树

标签:scan   har   mes   线段   utc   turn   testcase   oid   lse   

原文地址:https://www.cnblogs.com/Yinku/p/11039894.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!