- 思路:先说一下调了好久的bug而且是易犯得错,注意root.lazy传递给root*2.lazy时不是直接root*2.lazy=root.lazy
- 而是累计(+或*) 例如:root * 2.lazy + = root.lazy.并且这种+,*混合的要注意只要更新*,就必须更新+,无论是在
- updata还是down操作都是只要更新 * 就得更新+.
-
#include<bits/stdc++.h> using namespace std; #define ll long long #define maxn 155555 struct node { ll l, r, lazyplus, lazymul, sum; } tree[maxn*4]; ll n,m,mod,ans,a[maxn]; void up(int root) { tree[root].sum = (tree[root*2].sum+tree[root*2+1].sum) % mod; } void down(int root) { if(tree[root].lazymul == 1&&tree[root].lazyplus == 0) return ; tree[root*2].lazymul = (tree[root*2].lazymul % mod * tree[root].lazymul % mod) % mod; tree[root*2+1].lazymul = (tree[root*2+1].lazymul % mod * tree[root].lazymul % mod) % mod; tree[root*2].lazyplus = (tree[root].lazyplus%mod + tree[root*2].lazyplus % mod * tree[root].lazymul % mod) % mod; tree[root*2+1].lazyplus = (tree[root].lazyplus%mod + tree[root*2+1].lazyplus % mod * tree[root].lazymul % mod) % mod; tree[root*2].sum=( tree[root*2].sum * tree[root].lazymul % mod + (tree[root*2].r-tree[root*2].l+1) * tree[root].lazyplus % mod )%mod; tree[root*2+1].sum=(tree[root*2+1].sum * tree[root].lazymul % mod + (tree[root*2+1].r-tree[root*2+1].l+1)*tree[root].lazyplus % mod)%mod; tree[root].lazymul=1; tree[root].lazyplus=0; } void build(int root,int l,int r) { tree[root].l=l; tree[root].r=r; tree[root].lazymul=1; tree[root].lazyplus=0; tree[root].sum=0; if(l==r) { tree[root].sum=a[l]; return ; } int mid = (l+r)/2; build(root*2,l,mid); build(root*2+1,mid+1,r); up(root); } void updata(int root,int l,int r,ll ad,ll mu) { if(tree[root].l==l&&tree[root].r==r) { if(mu>0) { tree[root].lazymul=(tree[root].lazymul*mu)%mod; tree[root].sum=(tree[root].sum*mu)%mod; tree[root].lazyplus=(tree[root].lazyplus*mu)%mod; } else { tree[root].sum=(tree[root].sum%mod + ad*(tree[root].r-tree[root].l+1)%mod)%mod; tree[root].lazyplus=(tree[root].lazyplus+ad)%mod; } return ; } down(root); int mid=(tree[root].l+tree[root].r)/2; if(l>mid)updata(root*2+1,l,r,ad,mu); else if(r<=mid)updata(root*2,l,r,ad,mu); else { updata(root*2,l,mid,ad,mu); updata(root*2+1,mid+1,r,ad,mu); } up(root); } void query(int root,int l,int r) { if(tree[root].l==l&&tree[root].r==r) { ans=(ans+tree[root].sum)%mod; return ; } down(root); int mid=(tree[root].l+tree[root].r)/2; if(l>mid)query(root*2+1,l,r); else if(r<=mid)query(root*2,l,r); else { query(root*2,l,mid); query(root*2+1,mid+1,r); } } int main() { scanf("%lld %lld %lld",&n, &m, &mod); for(int i=1; i<=n; i++) scanf("%lld",&a[i]); build(1,1,n); ll orz,x,y,qq; while(m--) { ans=0; scanf("%lld%lld%lld",&orz,&x,&y); if(orz!=3)scanf("%lld",&qq); if(orz==2) updata(1,x,y,qq,0); else if(orz==1) updata(1,x,y,0,qq); else { query(1,x,y); printf("%lld\n",ans); } } return 0; }
P3373 【模板】线段树 +*混合操作
最新推荐文章于 2024-11-01 22:06:44 发布