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

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

这个板子不打就是手生……一段时间不会处理线段树了qwq,这个题难点就是在于下放标记

#include
#include
#include
using namespace std;typedef long long lo;lo n,p,m,a[100010],x,y,z,fl,qwq;struct in{ lo l,r,s,f1,f2;}ter[400040];inline void re(lo &c){ c=0; char b=getchar(); while(b<'0'||b>'9') b=getchar(); while(b>='0'&&b<='9') c=c*10+b-'0',b=getchar();}inline void u(lo w){ ter[w].s=((ter[w<<1].s%p)+(ter[w<<1|1].s%p))%p;}inline void build(lo l,lo r,lo w){ ter[w]=(in){l,r,0,1,0}; if(l==r) { ter[w].s=a[l];return; } lo mid=l+r>>1; build(l,mid,w<<1),build(mid+1,r,w<<1|1); u(w);}inline void d(lo w){ lo f1=ter[w].f1,f2=ter[w].f2; if(f1==1&&f2==0) return; ter[w<<1].f1*=f1,ter[w<<1].f1%=p;//不管加法还是乘法的flag都要乘上他们父亲的乘法flag ter[w<<1|1].f1*=f1,ter[w<<1|1].f1%=p; ter[w<<1].f2*=f1,ter[w<<1].f2%=p; ter[w<<1|1].f2*=f1,ter[w<<1|1].f2%=p; ter[w<<1].f2+=f2,ter[w<<1].f2%=p;//加法还要加上 ter[w<<1|1].f2+=f2,ter[w<<1|1].f2%=p; ter[w<<1].s*=f1,ter[w<<1].s%=p;//先乘再加 ter[w<<1|1].s*=f1,ter[w<<1|1].s%=p; ter[w<<1].s+=f2*(ter[w<<1].r-ter[w<<1].l+1),ter[w<<1].s%=p; ter[w<<1|1].s+=f2*(ter[w<<1|1].r-ter[w<<1|1].l+1),ter[w<<1|1].s%=p; ter[w].f1=1,ter[w].f2=0;//乘法的flag赋为1是因为最起码*1,不能*0 }void cha1(lo l,lo r,lo jia,lo w){ if(ter[w].l==l&&ter[w].r==r)//乘法是一起乘 { ter[w].f1*=jia,ter[w].f1%=p; ter[w].f2*=jia,ter[w].f2%=p; ter[w].s*=jia,ter[w].s%=p; return; } d(w); lo mid=ter[w].l+ter[w].r>>1; if(r<=mid) cha1(l,r,jia,w<<1); else if(l>mid) cha1(l,r,jia,w<<1|1); else cha1(l,mid,jia,w<<1),cha1(mid+1,r,jia,w<<1|1); u(w);}void cha2(lo l,lo r,lo jia,lo w){ if(ter[w].l==l&&ter[w].r==r)//加法是单独加在加法的flag上 { ter[w].f2+=jia,ter[w].f2%=p; ter[w].s+=jia*(ter[w].r-ter[w].l+1),ter[w].s%=p; return; } d(w); lo mid=ter[w].l+ter[w].r>>1; if(r<=mid) cha2(l,r,jia,w<<1); else if(l>mid) cha2(l,r,jia,w<<1|1); else cha2(l,mid,jia,w<<1),cha2(mid+1,r,jia,w<<1|1); u(w);}lo ask(lo l,lo r,lo w){ if(ter[w].l==l&&ter[w].r==r) return ter[w].s; lo mid=ter[w].l+ter[w].r>>1,re=0; d(w); if(r<=mid) re+=ask(l,r,w<<1)%p; else if(l>mid) re+=ask(l,r,w<<1|1)%p; else re+=ask(l,mid,w<<1)%p,re+=ask(mid+1,r,w<<1|1)%p; u(w); return re;}int main(){ re(n),re(p); for(int i=1;i<=n;i++) re(a[i]); build(1,n,1);//建树 re(m); for(int i=1;i<=m;i++) { re(fl),re(x),re(y); if(fl==1) re(z),cha1(x,y,z,1);//区间乘 if(fl==2) re(z),cha2(x,y,z,1);//区间加 if(fl==3) qwq=ask(x,y,1)%p,printf("%lld\n",qwq);//查询 }}

 

转载于:https://www.cnblogs.com/Loi-dfkdsmbd/articles/7806380.html

你可能感兴趣的文章
Sqoop往Hive导入数据实战
查看>>
Mysql到HBase的迁移
查看>>
Sqoop import进阶
查看>>
Hive语句是如何转化成MapReduce任务的
查看>>
Hive创建table报错:Permission denied: user=lenovo, access=WRITE, inode="":suh:supergroup:rwxr-xr-x
查看>>
Hive执行job时return code 2排查
查看>>
hive常用函数及数据结构介绍
查看>>
Hive面试题干货(亲自跟着做了好几遍,会了的话对面试大有好处)
查看>>
力扣题解-230. 二叉搜索树中第K小的元素(递归方法,中序遍历解决)
查看>>
力扣题解-123. 买卖股票的最佳时机 III(动态规划)
查看>>
Django 源码阅读:服务启动(wsgi)
查看>>
Django 源码阅读:url解析
查看>>
Docker面试题(一)
查看>>
第一轮面试题
查看>>
2020-11-18
查看>>
Docker面试题(二)
查看>>
一、redis面试题及答案
查看>>
消息队列2
查看>>
C++ 线程同步之临界区CRITICAL_SECTION
查看>>
测试—自定义消息处理
查看>>