【BZOJ】1798 [Ahoi2009]Seq 维护序列seq 线段树

来源:互联网 发布:淘宝的微淘怎么设置 编辑:程序博客网 时间:2024/05/16 05:38

题目传送门
这题的正解是线段树,这个其实还是比较好想的,因为这道题中的所有操作都是线段树的基本操作。
但是,这题的延迟标记有两个,这两个标记之间的关系是比较难想的,而且也是比较容易打错的……
这道题主要考察的是选手对于线段树的延迟标记的理解程度,整个程序最难打的也就是pushdown这个函数,我也在这个函数上WA了好几次。(这仅代表个人意见,如有同学认为这个函数好打,那你厉害了)

附上AC代码:

#include <cstdio>#define lt (k<<1)#define rt (k<<1|1)#define mid (l+r>>1)using namespace std;struct note{    long long jia,cheng,w;}t[300010];long long n,m,p,x,y,o,c,cheng,jia;void build(long long k,long long l,long long r){    t[k].jia=0,t[k].cheng=1;    if (l==r){        scanf("%lld",&t[k].w),t[k].w%=p;        return;    }    build(lt,l,mid);    build(rt,mid+1,r);    t[k].w=(t[lt].w+t[rt].w)%p;    return;}void push(long long k,long long l,long long r){    t[lt].w=(t[lt].w*t[k].cheng+(mid-l+1)*t[k].jia)%p;    t[lt].cheng=t[lt].cheng*t[k].cheng%p;    t[lt].jia=(t[lt].jia*t[k].cheng+t[k].jia)%p;    t[rt].w=(t[rt].w*t[k].cheng+(r-mid)*t[k].jia)%p;    t[rt].cheng=t[rt].cheng*t[k].cheng%p;    t[rt].jia=(t[rt].jia*t[k].cheng+t[k].jia)%p;    t[k].cheng=1,t[k].jia=0;return;}void change(long long k,long long l,long long r,long long ql,long long qr){    if (l>qr||r<ql) return;    if (l>=ql&&r<=qr){        t[k].w=(t[k].w*cheng+(r-l+1)*jia)%p;        t[k].cheng=t[k].cheng*cheng%p;        t[k].jia=(t[k].jia*cheng+jia)%p;        return;    }    push(k,l,r);    if (ql<=mid) change(lt,l,mid,ql,qr);    if (qr>mid) change(rt,mid+1,r,ql,qr);    t[k].w=(t[lt].w+t[rt].w)%p;    return;}long long query(long long k,long long l,long long r,long long ql,long long qr){    if (l>qr||r<ql) return 0;    if (l>=ql&&r<=qr) return t[k].w%p;    push(k,l,r);    long long ans=0;    if (ql<=mid) ans=(ans+query(lt,l,mid,ql,qr))%p;    if (qr>mid) ans=(ans+query(rt,mid+1,r,ql,qr))%p;    return ans%p;}int main(void){    scanf("%lld%lld",&n,&p);    build(1,1,n);    scanf("%lld",&m);    for (long long i=1; i<=m; ++i){        scanf("%lld%lld%lld",&o,&x,&y);        switch (o){            case 1:scanf("%lld",&cheng),jia=0,change(1,1,n,x,y);break;            case 2:scanf("%lld",&jia),cheng=1,change(1,1,n,x,y);break;            case 3:printf("%lld\n",query(1,1,n,x,y));break;        }    }    return 0;}
0 0