UESTC - 1597 An easy problem C (线段树)
2017-08-01 18:58
435 查看
An easy problem C
N个数排成一列,有三种操作。1.给一段区间内的每个数乘上一个非负整数。2.给一段区间内的每个数加上一个非负整数.3.询问一段区间的和模上P的值。Input
第一行两个整数N(1≤N≤100000)表示数的个数,P(1≤P≤1000000000)表示模的值。接下来一行N个整数ai(0≤ai≤1000000000),接下来一行一个整数M(1≤M≤100000)表示操作数量,接下来M行每行描述一个操作。第一种操作描述:1 L R C(0≤C≤1000000000),表示把L到R这段区间每个数乘上一个C。第二种操作描述:2 L R C(0≤C≤1000000000),表示把L到R这段区间每个数加上一个C。第三种操作3 L R 表示询问L到R这段区间内的数的和模上P的值。
Output
对面每个询问,输出对应的答案,每个询问占一行。
Sample Input
7 43
1 2 3 4 5 6 7
5
1 2 5 5
3 2 4
2 3 7 9
3 1 3
3 4 7
Sample Output
2
35
8
思路:hdu 4578弱化版,但是这道题应该注意的是mul[i]要初始为1
其他的依旧在Pushdown的时候,先更新mul,再更新add
代码:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; typedef long long LL; const LL maxn=1e5+10; struct Segtree { LL le,ri; LL val,add,mul; LL mid() { return (le+ri)>>1; } } tree[maxn<<2]; LL a[maxn]; LL n,mod; void fun_add(LL rt,LL num) { tree[rt].add=(tree[rt].add+num)%mod; LL len=tree[rt].ri-tree[rt].le+1; tree[rt].val=(tree[rt].val+(num*len)%mod)%mod; } void fun_mul(LL rt,LL num) { tree[rt].mul=(tree[rt].mul*num)%mod; tree[rt].add=(tree[rt].add*num)%mod; tree[rt].val=(tree[rt].val*num)%mod; } void Pushdown(LL rt) { if(tree[rt].mul!=1) { fun_mul(rt<<1,tree[rt].mul); fun_mul(rt<<1|1,tree[rt].mul); tree[rt].mul=1; } if(tree[rt].add) 4000 { fun_add(rt<<1,tree[rt].add); fun_add(rt<<1|1,tree[rt].add); tree[rt].add=0; } } void Pushup(LL rt) { tree[rt].val=(tree[rt<<1].val+tree[rt<<1|1].val)%mod; } void Build(LL rt,LL le,LL ri) { tree[rt].le=le,tree[rt].ri=ri; tree[rt].add=0; tree[rt].mul=1; if(le==ri) { tree[rt].val=a[le]; return ; } LL mid=tree[rt].mid(); Build(rt<<1,le,mid); Build(rt<<1|1,mid+1,ri); Pushup(rt); } void Update(LL rt,LL le,LL ri,LL num,LL op) { if(le<=tree[rt].le&&tree[rt].ri<=ri) { if(op==1) fun_mul(rt,num); else fun_add(rt,num); return ; } Pushdown(rt); LL mid=tree[rt].mid(); if(le<=mid) Update(rt<<1,le,ri,num,op); if(ri>mid) Update(rt<<1|1,le,ri,num,op); Pushup(rt); } LL Query(LL rt,LL le,LL ri) { if(le<=tree[rt].le&&tree[rt].ri<=ri) return tree[rt].val; Pushdown(rt); LL mid=tree[rt].mid(); LL ans=0; if(le<=mid) ans=(ans+Query(rt<<1,le,ri))%mod; if(ri>mid) ans=(ans+Query(rt<<1|1,le,ri))%mod; Pushup(rt); return ans; } int main() { scanf("%lld%lld",&n,&mod); for(LL i=1; i<=n; ++i) scanf("%lld",&a[i]); Build(1,1,n); LL op,x,y,m; LL c; scanf("%lld",&m); while(m--) { scanf("%lld",&op); if(op<=2) { scanf("%lld%lld%lld",&x,&y,&c); Update(1,x,y,c,op); } else { scanf("%lld%lld",&x,&y); printf("%lld\n",Query(1,x,y)); } } return 0; }
相关文章推荐
- UESTC - 1597 An easy problem C (线段树)
- UESTC - 1597 An easy problem C (线段树)
- UESTC - 1597 An easy problem C (线段树)
- UESTC - 1597 An easy problem C (线段树)
- UESTC - 1597 An easy problem C (线段树)
- UESTC - 1597 An easy problem C (线段树)
- UESTC - 1597 An easy problem C (线段树)
- UESTC - 1597 An easy problem C (线段树)
- UESTC - 1597 An easy problem C (线段树)
- UESTC - 1597 An easy problem C (线段树)
- UESTC - 1597 An easy problem C (线段树)
- UESTC - 1597 An easy problem C (线段树)
- UESTC - 1597 An easy problem C (线段树)
- UESTC - 1597 An easy problem C (线段树)
- UESTC 1591 An easy problem A【线段树点更新裸题】
- 线段树:CDOJ1597-An easy problem C(区间更新的线段树)
- hdu 5475 An easy problem(暴力 || 线段树区间单点更新)
- HDU-5475-An easy problem【线段树】
- hdu 5475 An easy problem(线段树单点更新)
- HDU-5475 An easy problem(模拟||(倒着计算+线段树))