洛谷3374 线段树2
来源:互联网 发布:io1.1鼠标淘宝哪家最好 编辑:程序博客网 时间:2024/06/07 12:28
题目描述
如题,已知一个数列,你需要进行下面两种操作:
1.将某区间每一个数加上x
2.将某区间每一个数乘上x
3.求出某区间每一个数的和
输入输出格式
输入格式:
第一行包含三个整数N、M、P,分别表示该数列数字的个数、操作的总个数和模数。
第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。
接下来M行每行包含3或4个整数,表示一个操作,具体如下:
操作1: 格式:1 x y k 含义:将区间[x,y]内每个数乘上k
操作2: 格式:2 x y k 含义:将区间[x,y]内每个数加上k
操作3: 格式:3 x y 含义:输出区间[x,y]内每个数的和对P取模所得的结果
输出格式:
输出包含若干行整数,即为所有操作3的结果。
输入输出样例
输入样例#1:
5 5 38
1 5 4 2 3
2 1 4 1
3 2 5
1 2 4 2
2 3 5 5
3 1 4
输出样例#1:
17
2
说明
时空限制:1000ms,128M
数据规模:
对于30%的数据:N<=8,M<=10
对于70%的数据:N<=1000,M<=10000
对于100%的数据:N<=100000,M<=100000
(数据已经过加强^_^)
样例说明:
故输出应为17、2(40 mod 38=2)
Q
注意:
1.取模要彻底!
2.先*后+;
3.lazy标记是+=不是只有=!;
4.push要加if判断;
在query中,用push后不用up是因为:父节点的值已经确定(push前),子节点的值没有修改;
push的前提就是父节点值已经确定,因此push完后lazy标记改为0;
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long ll;const ll MAXN=500001;ll n,m,p,num[MAXN];struct hh{ ll delta,l,r,sum,add;}tree[MAXN];void up(ll now){ tree[now].sum=((tree[now<<1].sum%p)+(tree[now<<1|1].sum%p))%p; return;}void build_tree(ll now,ll l,ll r){ ll mid=(l+r)>>1; tree[now].l=l; tree[now].r=r; tree[now].add=1; tree[now].delta=0; if(l==r) {tree[now].sum=num[l]%p;return;} build_tree(now<<1,l,mid); build_tree(now<<1|1,mid+1,r); up(now); return;}void push(ll now){ if(tree[now].add!=1) { tree[now<<1].add=(tree[now].add*tree[now<<1].add)%p; tree[now<<1].sum=(tree[now].add*tree[now<<1].sum)%p; tree[now<<1|1].add=(tree[now<<1|1].add*tree[now].add)%p; tree[now<<1|1].sum=(tree[now<<1|1].sum*tree[now].add)%p; tree[now<<1].delta=(tree[now<<1].delta*tree[now].add)%p; tree[now<<1|1].delta=(tree[now<<1|1].delta*tree[now].add)%p; tree[now].add=1; } if(tree[now].delta) { tree[now<<1].sum=(tree[now<<1].sum%p+(tree[now<<1].r-tree[now<<1].l+1)*tree[now].delta)%p; tree[now<<1].delta=(tree[now<<1].delta+tree[now].delta)%p; tree[now<<1|1].sum=(tree[now<<1|1].sum%p+(tree[now<<1|1].r-tree[now<<1|1].l+1)*tree[now].delta)%p; tree[now<<1|1].delta=(tree[now].delta+tree[now<<1|1].delta)%p; tree[now].delta=0; } return;}void change_1(ll now,ll l,ll r,ll v){ if(v==1) return; if(tree[now].l>=l && tree[now].r<=r) { tree[now].sum=(tree[now].sum*v)%p; tree[now].add=(tree[now].add*v)%p; tree[now].delta=(tree[now].delta*v)%p; return; } push(now); ll mid=(tree[now].l+tree[now].r)>>1; if(l<=mid) change_1(now<<1,l,r,v); if(r>=mid+1) change_1(now<<1|1,l,r,v); up(now); return;}void change_2(ll now,ll l,ll r,ll v){ if(tree[now].l>=l && tree[now].r<=r) { tree[now].sum=((tree[now].r-tree[now].l+1)*v+tree[now].sum)%p; tree[now].delta=(tree[now].delta+v)%p; return; } push(now); ll mid=(tree[now].l+tree[now].r)>>1; if(l<=mid) change_2(now<<1,l,r,v); if(r>=mid+1) change_2(now<<1|1,l,r,v); up(now); return;}ll query(ll now,ll l,ll r){ if(tree[now].l>=l && tree[now].r<=r) return tree[now].sum%p; push(now); ll ans=0,mid=(tree[now].l+tree[now].r)>>1; if(l<=mid) ans=(ans+query(now<<1,l,r))%p; if(r>=mid+1) ans=(ans+query(now<<1|1,l,r))%p; return ans%p;}void solve(){ cin>>n>>m>>p; for(ll i=1;i<=n;i++) scanf("%lld",&num[i]); build_tree(1,1,n); while(m--) { ll opt,x,y,k; scanf("%lld%lld%lld",&opt,&x,&y); switch(opt) { case 1: scanf("%lld",&k),change_1(1,x,y,k%p);break; case 2: scanf("%lld",&k),change_2(1,x,y,k%p);break; case 3: printf("%lld\n",query(1,x,y)%p);break; } } return;}int main(){ solve(); return 0;}
阅读全文
1 0
- 洛谷3374 线段树2
- 洛谷 P3373 【模板】线段树 2 (线段树)
- 【模板】线段树 洛谷 3372 线段树
- 洛谷 PP3373【模板】线段树 2
- 洛谷P3373 【模板】线段树2
- 洛谷 1609 线段树
- 线段树2
- hdu3974 线段树-2
- 线段树(2)
- 线段树练习 2
- 线段树2练习
- 线段树题型2
- 2维线段树
- 线段树查询2
- 无名线段树2
- 线段树模板2
- 线段树(2)
- 线段树练习2
- spring 连接oracle数据库的代码
- PAT 1066. Root of AVL Tree (25) 回レ!雪月AVL
- iOS 动态隐藏状态栏
- 洛谷 P3390 【模板】矩阵快速幂
- F2803X笔记——初始化与启动_#ifdef语句
- 洛谷3374 线段树2
- JavaScript类与封装
- Number Sequence(找规律,,,,,反正我没找到,递归超内存了....)
- CodeForces 735B Urbanization
- geotrellis使用(三十一)使用geotrellis直接将GeoTiff发布为TMS服务
- 响应式布局总结
- 火柴棍等式
- 7种Java单例模式
- Mybatis输入输出映射及动态sql