洛谷 P3373 【模板】线段树 2
程序员文章站
2022-06-17 09:06:29
[TOC] 题目 "戳" 思路 乘法优先(说了和没说一样,qwq) $Code$ cpp include include include include include define LL long long define MAXN 100001 using namespace std; LL n, ......
目录
题目
思路
乘法优先(说了和没说一样,qwq)
$code$
#include<iostream> #include<cstring> #include<cstdio> #include<string> #include<algorithm> #define ll long long #define maxn 100001 using namespace std; ll n,m,mod; struct node{ ll l,r,w,mul,add; }tree[maxn*4]; inline ll read(){ ll x=0;bool f=0;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=!f;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return f?-x:x; } void pushdown(ll now){ if(tree[now].l==tree[now].r) return; tree[now<<1].w=(tree[now<<1].w*tree[now].mul+tree[now].add*(tree[now<<1].r-tree[now<<1].l+1))%mod; tree[now<<1|1].w=(tree[now<<1|1].w*tree[now].mul+tree[now].add*(tree[now<<1|1].r-tree[now<<1|1].l+1))%mod; tree[now<<1].mul=(tree[now].mul*tree[now<<1].mul)%mod; tree[now<<1|1].mul=(tree[now].mul*tree[now<<1|1].mul)%mod; tree[now<<1].add=(tree[now<<1].add*tree[now].mul+tree[now].add)%mod; tree[now<<1|1].add=(tree[now<<1|1].add*tree[now].mul+tree[now].add)%mod; tree[now].mul=1,tree[now].add=0; return; } void build(ll l,ll r,ll now){ tree[now].mul=1; tree[now].l=l;tree[now].r=r; if(tree[now].l==tree[now].r){ tree[now].w=read(); return; } ll mid=(tree[now].l+tree[now].r)>>1; build(l,mid,now<<1);build(mid+1,r,now<<1|1); tree[now].w=tree[now<<1].w+tree[now<<1|1].w; tree[now].w%=mod; } void update_rmul(ll x,ll y,ll k,ll now){ if(y<tree[now].l||x>tree[now].r) return; if(tree[now].l>=x&&tree[now].r<=y){ tree[now].w=(tree[now].w*k)%mod; tree[now].mul=(tree[now].mul*k)%mod; tree[now].add=(tree[now].add*k)%mod; return; } pushdown(now); update_rmul(x,y,k,now<<1);update_rmul(x,y,k,now<<1|1); tree[now].w=(tree[now<<1].w+tree[now<<1|1].w)%mod; } void update_radd(ll x,ll y,ll k,ll now){ if(y<tree[now].l||x>tree[now].r) return; if(tree[now].l>=x&&tree[now].r<=y){ tree[now].add=(tree[now].add+k)%mod; tree[now].w=(tree[now].w+(tree[now].r-tree[now].l+1)*k)%mod; return; } pushdown(now); update_radd(x,y,k,now<<1);update_radd(x,y,k,now<<1|1); tree[now].w=(tree[now<<1].w+tree[now<<1|1].w)%mod; } ll ask_range(ll x,ll y,ll now){ if(y<tree[now].l||x>tree[now].r) return 0; if(tree[now].l>=x&&tree[now].r<=y) return tree[now].w; pushdown(now); return (ask_range(x,y,now<<1)+ask_range(x,y,now<<1|1))%mod; } int main(){ n=read(),m=read(),mod=read(); build(1,n,1); ll bz,x,y,k; while(m--){ bz=read(),x=read(),y=read(); if(bz==1){ k=read(); update_rmul(x,y,k,1); } if(bz==2){ k=read(); update_radd(x,y,k,1); } if(bz==3){ printf("%lld\n",ask_range(x,y,1)%mod); } } return 0; }
上一篇: img图片加载出错处理方法