【BZOJ/Luogu】1798/P3373 [Ahoi2009]Seq 维护序列seq/【模板】线段树 2 区间加、乘线段树

来源:互联网 发布:netgear 访客网络 编辑:程序博客网 时间:2024/06/05 16:13

20171014 大事件

题目交十次必定AC定理

RunIDUserProblemResultMemoryTimeLanguageCode_LengthSubmit_Time2353336FMM1798Accepted10984 kb5760 msC++/Edit3490 B2017-10-14 10:43:562352043FMM1798Wrong_Answer10984 kb964 msC++/Edit3469 B2017-10-13 17:02:202352042FMM1798Time_Limit_Exceed10976 kb30897 msC++/Edit3507 B2017-10-13 17:01:522352015FMM1798Wrong_Answer10984 kb908 msC++/Edit3478 B2017-10-13 16:52:172350510FMM1798Wrong_Answer10984 kb988 msC++/Edit3476 B2017-10-12 21:42:462350312FMM1798Wrong_Answer10980 kb852 msC++/Edit3211 B2017-10-12 21:05:372350249FMM1798Wrong_Answer10980 kb680 msC++/Edit3182 B2017-10-12 20:54:232349881FMM1798Runtime_Error10976 kb28 msC++/Edit3184 B2017-10-12 19:50:492349875FMM1798Runtime_Error5900 kb20 msC++/Edit2998 B2017-10-12 19:49:052349688FMM1798Runtime_Error5896 kb20 msC++/Edit2928 B2017-10-12 18:54:52

祖国江山一片红


这个程序和区间加的线段树有点不同

区间加时不需要tag_down

而这里的区间加操作则需要下放标记


/**************************************************************    Problem: 1798    User: FMM    Language: C++    Result: Accepted    Time:5760 ms    Memory:10984 kb****************************************************************/ #include <cstdio>#define C (c=getchar())using namespace std; struct wjnsb{    long long val,mult,plus;}a[400005]; long long opt,m,n,INF,ori[100005]; inline void read(long long &n){    long long f=1;char c;n=0;C;    while (c<'0'||c>'9') c=='-'?f=-1,C:C;    while (c>='0'&&c<='9') n=(n<<3)+(n<<1)+c-48,C;    return (void)(n*=f);} void bt(long long q,long long l,long long r){    if (l==r)    {        a[q].mult=1;        return (void)(a[q].val=ori[l]%INF);    }    a[q].mult=1;    bt(q<<1,l,(l+r)>>1),bt((q<<1)+1,((l+r)>>1)+1,r);    a[q].val=a[q<<1].val%INF+a[(q<<1)+1].val%INF;    a[q].val%=INF;    return;} void tag_down(long long x,long long l,long long r){    int mid=(l+r)>>1;    if (a[x].mult==1&&a[x].plus==0) return;    if (l==r) return;    a[x<<1].val=a[x<<1].val*a[x].mult%INF+(mid-l+1)*a[x].plus%INF;    a[(x<<1)+1].val=a[(x<<1)+1].val*a[x].mult%INF+(r-mid)*a[x].plus%INF;    a[x<<1].val%=INF;    a[(x<<1)+1].val%=INF;    a[x<<1].mult*=a[x].mult%INF;    a[(x<<1)+1].mult*=a[x].mult%INF;    a[x<<1].plus=a[x<<1].plus*a[x].mult%INF+a[x].plus%INF;    a[(x<<1)+1].plus=a[(x<<1)+1].plus*a[x].mult%INF+a[x].plus%INF;    a[x<<1].mult%=INF;    a[(x<<1)+1].mult%=INF;    a[x<<1].plus%=INF;    a[(x<<1)+1].plus%=INF;    a[x].mult=1;a[x].plus=0;    return;} void reval(long long x){return (void)(a[x].val=(a[x<<1].val%INF+a[(x<<1)+1].val%INF)%INF);} void mult(long long q,long long L,long long R,long long l,long long r,long long x){    if (L==l&&R==r)    {        a[q].plus*=x;        a[q].plus%=INF;        a[q].val*=x;        a[q].val%=INF;        a[q].mult*=x;        a[q].mult%=INF;        return;    }    long long mid=(L+R)>>1;    tag_down(q,L,R);    if (r<=mid)    {        mult(q<<1,L,mid,l,r,x);        reval(q);    }    else    if (l>mid)    {        mult((q<<1)+1,mid+1,R,l,r,x);        reval(q);    }    else    {        mult(q<<1,L,mid,l,mid,x);        mult((q<<1)+1,mid+1,R,mid+1,r,x);        reval(q);    }    return;} void plus(long long q,long long L,long long R,long long l,long long r,long long x){    if (L==l&&R==r)    {        a[q].plus+=x;        a[q].plus%=INF;        a[q].val+=x*(r-l+1);        a[q].val%=INF;        return;    }    long long mid=(L+R)>>1;    tag_down(q,L,R);    a[q].val+=x*(r-l+1);    a[q].val%=INF;    if (r<=mid)        plus(q<<1,L,mid,l,r,x);    else    if (l>mid)        plus((q<<1)+1,mid+1,R,l,r,x);    else    {        plus(q<<1,L,mid,l,mid,x);        plus((q<<1)+1,mid+1,R,mid+1,r,x);    }    return;} long long query(long long q,long long L,long long R,long long l,long long r){    if (L==l&&R==r) return a[q].val;    long long mid=(L+R)>>1;    tag_down(q,L,R);    if (r<=mid)    {        return query(q<<1,L,mid,l,r)%INF;    }    else    if (l>mid)    {        return query((q<<1)+1,mid+1,R,l,r)%INF;    }    else    {        return query(q<<1,L,mid,l,mid)%INF+query((q<<1)+1,mid+1,R,mid+1,r)%INF;    }} int main(void){    long long q,w,e;    read(n),read(INF);    for (register int i=1;i<=n;++i) read(ori[i]);    bt(1,1,n);    read(m);    for (register int i=1;i<=m;++i)    {        read(opt),read(q),read(w);        if (opt==1)        {            read(e);            mult(1,1,n,q,w,e%INF);        }        else        if (opt==2)        {            read(e);            plus(1,1,n,q,w,e%INF);        }        else        {            printf("%lld\n",query(1,1,n,q,w)%INF);        }    }    return 0;}


阅读全文
0 0
原创粉丝点击