hdu 4578

来源:互联网 发布:剑网三男神捏脸数据 编辑:程序博客网 时间:2024/04/29 18:10

      很明显的线段树的题目,但是挺麻烦的,三个lazy,三个值,并且lazy之间的关系要处理好。加法的操作需要推一下。

#include <iostream>#include <cstdio>#include <cstring>#define ls t<<1#define rs t<<1|1#define midt (tr[t].l+tr[t].r)>>1using namespace std;const int maxn=1e5+9;const int mod=10007;struct{    int l,r;    long long p1,p2,p3;    long long lazyadd,lazymul,lazyset;}tr[maxn<<2];void modifyadd(int t,int l,int r,long long tmp);void modifymul(int t,int l,int r,long long tmp);void modifyset(int t,int l,int r,long long tmp);void pushdown(int t){    if(tr[t].lazyset!=-1)    {        modifyset(ls,tr[ls].l,tr[ls].r,tr[t].lazyset);        modifyset(rs,tr[rs].l,tr[rs].r,tr[t].lazyset);        tr[t].lazyset=-1;    }    else    {        if(tr[t].lazymul!=1)        {            modifymul(ls,tr[ls].l,tr[ls].r,tr[t].lazymul);            modifymul(rs,tr[rs].l,tr[rs].r,tr[t].lazymul);            tr[t].lazymul=1;        }        if(tr[t].lazyadd)        {            modifyadd(ls,tr[ls].l,tr[ls].r,tr[t].lazyadd);            modifyadd(rs,tr[rs].l,tr[rs].r,tr[t].lazyadd);            tr[t].lazyadd=0;        }    }}void maketree(int t,int l,int r){    tr[t].l=l;    tr[t].r=r;    tr[t].p1=tr[t].p2=tr[t].p3=0;    tr[t].lazyadd=0;    tr[t].lazymul=1;    tr[t].lazyset=-1;    if(l==r) return ;    int mid=midt;    maketree(ls,l,mid);    maketree(rs,mid+1,r);}void modifyadd(int t,int l,int r,long long tmp){    if(l==tr[t].l&&r==tr[t].r)    {        int lon=tr[t].r-tr[t].l+1;        tr[t].p3+=tr[t].p2*3*tmp;        tr[t].p3%=mod;        tr[t].p3+=3*tmp*tmp*tr[t].p1;        tr[t].p3%=mod;        tr[t].p3+=tmp*tmp*tmp*lon;        tr[t].p3%=mod;        tr[t].p2+=2*tmp*tr[t].p1;        tr[t].p2%=mod;        tr[t].p2+=tmp*tmp*lon;        tr[t].p2%=mod;        tr[t].p1+=tmp*lon;        tr[t].p1%=mod;        if(tr[t].lazyset!=-1)        {            tr[t].lazyset+=tmp;            tr[t].lazyset%=mod;        }        else        {            tr[t].lazyadd+=tmp;            tr[t].lazyadd%=mod;        }        return ;    }    pushdown(t);    int mid=midt;    if(r<=mid)    modifyadd(ls,l,r,tmp);    else if(mid+1<=l)    modifyadd(rs,l,r,tmp);    else    {        modifyadd(ls,l,mid,tmp);        modifyadd(rs,mid+1,r,tmp);    }    tr[t].p1=tr[ls].p1+tr[rs].p1;    tr[t].p1%=mod;    tr[t].p2=tr[ls].p2+tr[rs].p2;    tr[t].p2%=mod;    tr[t].p3=tr[ls].p3+tr[rs].p3;    tr[t].p3%=mod;}void modifymul(int t,int l,int r,long long tmp){    if(l==tr[t].l&&r==tr[t].r)    {        tr[t].p1*=tmp;        tr[t].p1%=mod;        tr[t].p2*=tmp*tmp;        tr[t].p2%=mod;        tr[t].p3*=tmp*tmp*tmp;        tr[t].p3%=mod;        if(tr[t].lazyset!=-1)        {            tr[t].lazyset*=tmp;            tr[t].lazyset%=mod;        }        else        {            tr[t].lazyadd*=tmp;            tr[t].lazyadd%=mod;            tr[t].lazymul*=tmp;            tr[t].lazymul%=mod;        }//        printf("%d %d %d\n",tr[t].l,tr[t].r,tr[t].p1);        return ;    }    pushdown(t);    int mid=midt;    if(r<=mid)    modifymul(ls,l,r,tmp);    else if(mid+1<=l)    modifymul(rs,l,r,tmp);    else    {        modifymul(ls,l,mid,tmp);        modifymul(rs,mid+1,r,tmp);    }    tr[t].p1=tr[ls].p1+tr[rs].p1;    tr[t].p1%=mod;    tr[t].p2=tr[ls].p2+tr[rs].p2;    tr[t].p2%=mod;    tr[t].p3=tr[ls].p3+tr[rs].p3;    tr[t].p3%=mod;//    printf("%d %d %d\n",tr[t].l,tr[t].r,tr[t].p1);}void modifyset(int t,int l,int r,long long tmp){    if(l==tr[t].l&&r==tr[t].r)    {        int lon=tr[t].r-tr[t].l+1;        tr[t].p1=tmp*lon;        tr[t].p1%=mod;        tr[t].p2=tmp*tmp*lon;        tr[t].p2%=mod;        tr[t].p3=tmp*tmp*tmp*lon;        tr[t].p3%=mod;        tr[t].lazyset=tmp;        tr[t].lazyadd=0;        tr[t].lazymul=1;//        printf("%d %d %d\n",tr[t].l,tr[t].r,tr[t].lazyset);        return ;    }    pushdown(t);    int mid=midt;    if(r<=mid)    modifyset(ls,l,r,tmp);    else if(mid+1<=l)    modifyset(rs,l,r,tmp);    else    {        modifyset(ls,l,mid,tmp);        modifyset(rs,mid+1,r,tmp);    }    tr[t].p1=tr[ls].p1+tr[rs].p1;    tr[t].p1%=mod;    tr[t].p2=tr[ls].p2+tr[rs].p2;    tr[t].p2%=mod;    tr[t].p3=tr[ls].p3+tr[rs].p3;    tr[t].p3%=mod;//    printf("%d %d %d\n",tr[t].l,tr[t].r,tr[t].p1);}int query(int t,int l,int r,int p){//    printf("%d %d %d\n",tr[t].l,tr[t].r,tr[t].p1);    if(l==tr[t].l&&r==tr[t].r)    {        //printf("%d %d %d\n",tr[t].l,tr[t].r,tr[t].p1);        if(p==1) return tr[t].p1;        if(p==2) return tr[t].p2;        if(p==3) return tr[t].p3;    }    pushdown(t);    int mid=midt;    if(r<=mid)    return query(ls,l,r,p);    else if(mid+1<=l)    return query(rs,l,r,p);    else    {        int ret=query(ls,l,mid,p);        ret+=query(rs,mid+1,r,p);        ret%=mod;        return ret;    }}int main(){    freopen("in.txt","r",stdin);    int n,m;    while(scanf("%d %d",&n,&m),n|m)    {        maketree(1,1,n);        for(int i=1,tmp,l,r,c;i<=m;i++)        {            scanf("%d %d %d %d",&tmp,&l,&r,&c);            if(tmp==1)            modifyadd(1,l,r,c);            else if(tmp==2)            modifymul(1,l,r,c);            else if(tmp==3)            modifyset(1,l,r,c);            else            printf("%d\n",query(1,l,r,c));        }    }    return 0;}



原创粉丝点击