BZOJ-1798: [Ahoi2009]Seq 维护序列seq

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1798

思路:这是一道裸的线段树,但是维护标记的时候要小心乘的标记在MOD之后成为0的情况(为此我WA了N次555)

代码:

#include 

#include 

  

#define MAXN 100001

  

struct node {

    int l,r;

    long long s,M,A;

    node (){

        M=1;

        A=0;

    }

} T[MAXN*4];

  

int a[MAXN];

int n,p,m;

  

void Build(int l,int r,int t) {

    T[t].l=l;

    T[t].r=r;

    if (l==r) {

        T[t].s=a[l]%p;

        return ;

    }

    Build(l,(l+r)>>1,t<<1);

    Build(((l+r)>>1)+1,r,(t<<1)^1);

    T[t].s=(T[t<<1].s+T[(t<<1)^1].s)%p;

}

  

void Change(int l,int r,long long k,int t,int flag) {

    if (flag==1) {

        if (l==T[t].l&&r==T[t].r) {

            T[t].M=T[t].M*k;

            T[t].M%=p;

            if (!T[t].M) T[t].M=p;

            T[t].s=T[t].s*k;

            T[t].s%=p;

            T[t].A=T[t].A*k;

            T[t].A%=p;

            return ;

        }

        int mid=(T[t].l+T[t].r)>>1;

        if (T[t].M>1) {

            Change(T[t].l,mid,T[t].M,t<<1,1);

            Change(mid+1,T[t].r,T[t].M,(t<<1)^1,1);

            T[t].M=1;

        }

        if (T[t].A) {

            Change(T[t].l,mid,T[t].A,t<<1,2);

            Change(mid+1,T[t].r,T[t].A,(t<<1)^1,2);

            T[t].A=0;

        }

        if (r<=mid) Change(l,r,k,t<<1,1)

        ; else if (l>mid) Change(l,r,k,(t<<1)^1,1)

        ; else {

            Change(l,mid,k,t<<1,1);

            Change(mid+1,r,k,(t<<1)^1,1);

        }

    } else {

        if (l==T[t].l&&r==T[t].r) {

            long long ret=(r-l+1)*k;

            ret%=p;

            T[t].s=T[t].s+ret;

            T[t].s%=p;

            T[t].A=T[t].A+k;

            T[t].A%=p;

            return ;

        }

        int mid=(T[t].l+T[t].r)>>1;

        if (T[t].M>1) {

            Change(T[t].l,mid,T[t].M,t<<1,1);

            Change(mid+1,T[t].r,T[t].M,(t<<1)^1,1);

            T[t].M=1;

        }

        if (T[t].A) {

            Change(T[t].l,mid,T[t].A,t<<1,2);

            Change(mid+1,T[t].r,T[t].A,(t<<1)^1,2);

            T[t].A=0;

        }

        if (r<=mid) Change(l,r,k,t<<1,2)

        ; else if (l>mid) Change(l,r,k,(t<<1)^1,2)

        ; else {

            Change(l,mid,k,t<<1,2);

            Change(mid+1,r,k,(t<<1)^1,2);

        }

    }

    T[t].s=(T[t<<1].s+T[(t<<1)^1].s);

    T[t].s%=p;

}

  

long long Sum(int l,int r,int t) {

    if (l==T[t].l&&r==T[t].r) return T[t].s;

    int mid=(T[t].l+T[t].r)>>1;

    long long rec;

    if (r<=mid) rec=Sum(l,r,t<<1)

    ; else if (l>mid) rec=Sum(l,r,(t<<1)^1)

    ; else rec=(Sum(l,mid,t<<1)+Sum(mid+1,r,(t<<1)^1)),rec%=p;

    rec=(rec*T[t].M);

    rec%=p;

    long long ret=T[t].A*(r-l+1);

    rec=(rec+ret);

    rec%=p;

    return rec;

}

 

int main() {

    scanf("%d%d",&n,&p);

    for (int i=0;i++

你可能感兴趣的:(BZOJ-1798: [Ahoi2009]Seq 维护序列seq)