博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
题解 P2023 【[AHOI2009]维护序列】
阅读量:5233 次
发布时间:2019-06-14

本文共 4116 字,大约阅读时间需要 13 分钟。

一定要多取膜!不然一直卡60分!

在区间中进行更新并查询,很好想到用线段树

为了增加速度,我们可以用到lazy标记,不过这题有乘法,我们需要修改一下

定义结构体:

struct SegmentTree{    long long l,r;    long long sum;    long long addmark=0,mulmark=1;//加法的标记和乘法的标记}t[400010];//四倍开点

乘法更新:

if(x<=l&&y>=r)    {        t[id].sum=v%p*t[id].sum%p;        t[id].mulmark=t[id].mulmark*v%p;//乘标要乘上去        t[id].addmark=t[id].addmark*v%p;//加标也要乘(想一想为什么?)        return;    }

加法更新

if(x<=l&&y>=r)    {        t[id].sum=(t[id].sum+v%p*(r-l+1)%p)%p;//这个不用解释吧        t[id].addmark=(t[id].addmark+v%p)%p;        return;    }

下传标记

void PushDown(long long id){    t[id*2].mulmark=t[id].mulmark%p*t[id*2].mulmark%p;//乘标是乘上去的    t[id*2+1].mulmark=t[id].mulmark%p*t[id*2+1].mulmark%p;    t[id*2].addmark=(t[id*2].addmark%p*t[id].mulmark%p+t[id].addmark)%p;//加标要乘上下传下来的乘标    t[id*2+1].addmark=(t[id*2+1].addmark%p*t[id].mulmark%p+t[id].addmark)%p;    t[id*2].sum=(t[id].mulmark%p*t[id*2].sum%p+t[id].addmark*(t[id*2].r-t[id*2].l+1)%p)%p;//先乘后加    t[id*2+1].sum=(t[id].mulmark%p*t[id*2+1].sum%p+t[id].addmark*(t[id*2+1].r-t[id*2+1].l+1)%p)%p;    t[id].addmark=0;//记得清0    t[id].mulmark=1;}

贴完整代码

#include
#define lson id*2,l,mid#define rson id*2+1,mid+1,rusing namespace std;long long n,m,p;struct SegmentTree{ long long l,r; long long sum; long long addmark=0,mulmark=1;}t[400010];void BuildTree(long long,long long,long long);void Update1(long long,long long,long long,long long,long long,long long);void Update2(long long,long long,long long,long long,long long,long long);long long Query(long long,long long,long long,long long,long long);void PushDown(long long);int main(){ scanf("%lld%lld",&n,&p); BuildTree(1,1,n); scanf("%lld",&m); for(long long i=1;i<=m;i++) { long long k; scanf("%lld",&k); if(k==1) { long long x,y,o; scanf("%lld%lld%lld",&x,&y,&o); Update1(1,1,n,x,y,o); } if(k==2) { long long x,y,o; scanf("%lld%lld%lld",&x,&y,&o); Update2(1,1,n,x,y,o); } if(k==3) { long long x,y; scanf("%lld%lld",&x,&y); printf("%lld\n",Query(1,1,n,x,y)%p); } }return 0;}void BuildTree(long long id,long long l,long long r){ t[id].l=l; t[id].r=r; if(l==r) { scanf("%lld",&t[id].sum); return; } long long mid=(l+r)>>1; BuildTree(lson); BuildTree(rson); t[id].sum=(t[id*2].sum+t[id*2+1].sum)%p;}void Update1(long long id,long long l,long long r,long long x,long long y,long long v){ long long mid=(l+r)>>1; if(x<=l&&y>=r) { t[id].sum=v%p*t[id].sum%p; t[id].mulmark=t[id].mulmark*v%p; t[id].addmark=t[id].addmark*v%p; return; } PushDown(id); if(x<=mid)Update1(id*2,l,mid,x,y,v); if(y>mid)Update1(id*2+1,mid+1,r,x,y,v); t[id].sum=(t[id*2].sum+t[id*2+1].sum)%p;}void Update2(long long id,long long l,long long r,long long x,long long y,long long v){ long long mid=(l+r)>>1; if(x<=l&&y>=r) { t[id].sum=(t[id].sum+v%p*(r-l+1)%p)%p; t[id].addmark=(t[id].addmark+v%p)%p; return; } PushDown(id); if(x<=mid)Update2(id*2,l,mid,x,y,v); if(y>mid)Update2(id*2+1,mid+1,r,x,y,v); t[id].sum=(t[id*2].sum+t[id*2+1].sum)%p;}long long Query(long long id,long long l,long long r,long long x,long long y){ long long mid=(l+r)>>1; long long sum=0; if(x<=l&&y>=r)return t[id].sum; PushDown(id); if(x<=mid)sum=(sum+Query(id*2,l,mid,x,y))%p; if(y>mid)sum=(sum+Query(id*2+1,mid+1,r,x,y))%p; return sum;}void PushDown(long long id){ t[id*2].mulmark=t[id].mulmark%p*t[id*2].mulmark%p; t[id*2+1].mulmark=t[id].mulmark%p*t[id*2+1].mulmark%p; t[id*2].addmark=(t[id*2].addmark%p*t[id].mulmark%p+t[id].addmark)%p; t[id*2+1].addmark=(t[id*2+1].addmark%p*t[id].mulmark%p+t[id].addmark)%p; t[id*2].sum=(t[id].mulmark%p*t[id*2].sum%p+t[id].addmark*(t[id*2].r-t[id*2].l+1)%p)%p; t[id*2+1].sum=(t[id].mulmark%p*t[id*2+1].sum%p+t[id].addmark*(t[id*2+1].r-t[id*2+1].l+1)%p)%p; t[id].addmark=0; t[id].mulmark=1;}

转载于:https://www.cnblogs.com/Lemir3/p/10336702.html

你可能感兴趣的文章
html之novalidate
查看>>
mysql数学函数
查看>>
S-HR之变动操作,变动原因,变动类型/离职操作,离职原因,离职类型
查看>>
拆分字符串
查看>>
jq的each和map遍历
查看>>
js--script和link中的 integrity 属性
查看>>
xss攻击
查看>>
HTML DOM querySelector() 方法
查看>>
??条件判断
查看>>
千万不要误以为1个server只允许连接65535个Client。记住,TCP连出受端口限制,连入仅受内存限制...
查看>>
novalidate
查看>>
label for标签的作用
查看>>
uml多重性
查看>>
fastjson @JsonField
查看>>
jvm配置
查看>>
重载类型运算符
查看>>
EasyUI学习-如何使用jQuery EasyUI?
查看>>
前端JS之HTML利用XMLHttpRequest()和FormData()进行大文件分段上传
查看>>
jQuery获取Select选择的Text和 Value
查看>>
hdu1525 Euclid&#39;s Game , 基础博弈
查看>>