jzyzOJ 1658【bzoj1798改编】

#include<iostream>
#include<cstring>
#include<cstdio>
#include<ctime>
#include<algorithm>
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define INF 2100000000
#define maxn 100100
#define intt long long
#define mo 5201314
using namespace std;
intt ax,ay,x,y,q,c;
intt n,m;
struct qaq{
    intt maxx,deladd;
    intt delx;
}tree[maxn*4];

intt read(){
    intt f=1;
    intt k=0;
    char c=getchar();
    while(c>'9'||c<'0'){
        if(c=='-') f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        k=(k<<3)+(k<<1)+c-'0';
        c=getchar();
    }
    return f*k;
}

void push_down(intt id,intt l,intt r){
    if(tree[id].delx==1&&tree[id].deladd==0) return;
    intt tad=tree[id].deladd;
    intt txx=tree[id].delx;
    intt mid=(l+r)>>1;
    tree[L(id)].deladd=(tree[L(id)].deladd*txx+tad)%mo;
    tree[R(id)].deladd=(tree[R(id)].deladd*txx+tad)%mo;
    tree[L(id)].delx=(tree[L(id)].delx*txx)%mo;
    tree[R(id)].delx=(tree[R(id)].delx*txx)%mo;
    tree[L(id)].maxx=(tree[L(id)].maxx*txx+(mid-l+1)*tad)%mo;
    tree[R(id)].maxx=(tree[R(id)].maxx*txx+(r-(mid+1)+1)*tad)%mo;
    tree[id].deladd=0;
    tree[id].delx=1;
    return;
}

void build(intt l,intt r,intt id,intt v){
    if(l>y||r<x) return;
    tree[id].delx=1;
    tree[id].deladd=0;
    if(x<=l&&r<=y){
        tree[id].maxx=v;
        //cout<<v<<endl;
        return;
    }
    intt mid=(l+r)>>1;
    build(l,mid,L(id),v);
    build(mid+1,r,R(id),v);
    tree[id].maxx=(tree[L(id)].maxx+tree[R(id)].maxx)%mo;
    //cout<<tree[id].maxx<<endl;
    return;
}

void updatax(intt l,intt r,intt id,intt v){
    if(l>y||r<x) return;
    if(x<=l&&r<=y){
        tree[id].deladd=(tree[id].deladd*v)%mo;
        tree[id].delx=(tree[id].delx*v)%mo;
        tree[id].maxx=(tree[id].maxx*v)%mo;
        return;
    }
    push_down(id,l,r);
    intt mid=(l+r)>>1;
    updatax(l,mid,L(id),v);
    updatax(mid+1,r,R(id),v);
    tree[id].maxx=(tree[L(id)].maxx+tree[R(id)].maxx)%mo;
    return;
}

void updataadd(intt l,intt r,intt id,intt v){
    if(l>y||r<x) return;
    if(x<=l&&r<=y){
        tree[id].deladd=(tree[id].deladd+v)%mo;
        tree[id].maxx=(tree[id].maxx+(r-l+1)*v)%mo;
        return;
    }
    push_down(id,l,r);
    intt mid=(l+r)>>1;
    updataadd(l,mid,L(id),v);
    updataadd(mid+1,r,R(id),v);
    tree[id].maxx=(tree[L(id)].maxx+tree[R(id)].maxx)%mo;
    return;
}

intt findit(int l,int r,int id){
    if(l>y||r<x) return 0;
    if(x<=l&&r<=y){
        //cout<<tree[id].
        return tree[id].maxx%mo;
    }
    push_down(id,l,r);
    intt mid=(l+r)>>1;
    intt t1=findit(l,mid,L(id));
    intt t2=findit(mid+1,r,R(id));
    return (t1+t2)%mo;
}

int main(){
    //freopen("a.txt","r",stdin);
    //freopen("b.txt","w",stdout);
    memset(tree,0,sizeof(tree));
    n=read();
    m=read();
    //cout<<n<<' '<<m<<endl;
    for(int i=1;i<=n;++i){
        c=read();
        x=y=i;
        build(1,n,1,c);
    }
    for(int i=1;i<=m;++i){
        q=read();
        ax=read();
        ay=read();
        if(q==1){
            x=ax;
            y=ay;
            c=read();
            updatax(1,n,1,c);
        }
        else if(q==2){
            x=ax;
            y=ay;
            c=read();
            updataadd(1,n,1,c);
        }
        else{
            x=ax;
            y=ay;
            cout<<findit(1,n,1)%mo<<endl;
        }
    }
    //cout<<"Runtime:"<<double(1.0*clock()/1000.0)<<"S!"<<endl;
    return 0;
}
View Code

先放代码.....

这道题的难点在于1号操作,也就是乘法。裸的线段树,但是是双偏移量,还要控制好次序,代码慢慢看就行了。。

 

posted @ 2017-03-31 22:01  Strork  阅读(177)  评论(0编辑  收藏  举报