多功能線段樹模板(完善中)
阿新 • • 發佈:2021-12-14
已完成區間加,區間乘,區間覆蓋,區間求和,區間求min\max
#include<bits/stdc++.h> #define ll long long #define ls a[k].son[0] #define rs a[k].son[1] #define pls(a,b) a=((a)+(b))%mod #define mul(a,b) a=((a)*(b))%mod using namespace std; const ll mod=998244353; const int N=5e5+11; const ll inf=1e18; int tot,rt; struct SegmentTree{ struct Node{ int son[2]; ll sum,maxn,minn; ll tag_p,tag_m=1,tag_c; bool is_c; //define that tag_c>tag_m>tag_p }a[N*31]; void pushdown(int k,ll l,ll r){ if(!ls)ls=++tot; if(!rs)rs=++tot; ll mid=(l+r)>>1; if(a[k].is_c){ a[ls].sum=(mid-l+1)*a[k].tag_c%mod; a[rs].sum=(r-mid)*a[k].tag_c%mod; a[ls].tag_c=a[rs].tag_c=a[k].tag_c; a[ls].is_c=a[rs].is_c=1; a[ls].tag_p=a[rs].tag_p=0; a[ls].tag_m=a[rs].tag_m=1; a[ls].minn=a[rs].minn=a[ls].maxn=a[rs].maxn=a[k].tag_c; a[k].is_c=0;a[k].tag_c=0; } if(a[k].tag_m!=1){ ll s=a[k].tag_m; mul(a[ls].sum,s); mul(a[rs].sum,s); mul(a[ls].minn,s); mul(a[rs].minn,s); mul(a[ls].maxn,s); mul(a[rs].maxn,s); mul(a[ls].tag_p,s); mul(a[rs].tag_p,s); mul(a[ls].tag_m,s); mul(a[rs].tag_m,s); a[k].tag_m=1; } if(a[k].tag_p){ ll s=a[k].tag_p; pls(a[ls].sum,(mid-l+1)*s%mod); pls(a[rs].sum,(r-mid)*s%mod); pls(a[ls].minn,s); pls(a[rs].minn,s); pls(a[ls].maxn,s); pls(a[rs].maxn,s); pls(a[ls].tag_p,s); pls(a[rs].tag_p,s); a[k].tag_p=0; } } void pushup(int k){ a[k].sum=a[ls].sum+a[rs].sum; a[k].minn=min(a[ls].minn,a[rs].minn); a[k].maxn=max(a[ls].maxn,a[rs].maxn); } void add(int &k,ll l,ll r,ll L,ll R,ll s){ if(!k)k=++tot; if(l>=L&&r<=R){ pls(a[k].sum,s*(r-l+1)); pls(a[k].maxn,s); pls(a[k].minn,s); pls(a[k].tag_p,s); return; } pushdown(k,l,r); ll mid=(l+r)>>1; if(L<=mid)add(ls,l,mid,L,R,s); if(R>mid)add(rs,mid+1,r,L,R,s); pushup(k); } void cover(int &k,ll l,ll r,ll L,ll R,ll s){ if(!k)k=++tot; if(l>=L&&r<=R){ a[k].is_c=1; a[k].tag_c=s; a[k].tag_p=0; a[k].tag_m=1; a[k].sum=s*(r-l+1)%mod; a[k].maxn=a[k].minn=s; return; } pushdown(k,l,r); ll mid=(l+r)>>1; if(L<=mid)cover(ls,l,mid,L,R,s); if(R>mid)cover(rs,mid+1,r,L,R,s); pushup(k); } void multi(int &k,ll l,ll r,ll L,ll R,ll s){ if(!k)k=++tot; if(l>=L&&r<=R){ mul(a[k].tag_p,s); mul(a[k].tag_m,s); mul(a[k].sum,s); mul(a[k].minn,s); mul(a[k].maxn,s); return; } pushdown(k,l,r); ll mid=(l+r)>>1; if(L<=mid)multi(ls,l,mid,L,R,s); if(R>mid)multi(rs,mid+1,r,L,R,s); pushup(k); } ll qsum(int k,ll l,ll r,ll L,ll R){ if(!k)return 0; if(l>=L&&r<=R)return a[k].sum; pushdown(k,l,r); ll ret=0,mid=(l+r)>>1; if(L<=mid)ret+=qsum(ls,l,mid,L,R); if(R>mid)ret+=qsum(rs,mid+1,r,L,R); ret%=mod; return ret; } ll qmax(int k,ll l,ll r,ll L,ll R){ if(!k)return -inf; if(l>=L&&r<=R)return a[k].maxn; pushdown(k,l,r); ll ret=-inf,mid=(l+r)>>1; if(L<=mid)ret=max(ret,qmax(ls,l,mid,L,R)); if(R>mid)ret=max(ret,qmax(rs,mid+1,r,L,R)); return ret; } ll qmin(int k,ll l,ll r,ll L,ll R){ if(!k)return inf; if(l>=L&&r<=R)return a[k].minn; pushdown(k,l,r); ll ret=inf,mid=(l+r)>>1; if(L<=mid)ret=min(ret,qmin(ls,l,mid,L,R)); if(R>mid)ret=min(ret,qmin(rs,mid+1,r,L,R)); return ret; } }t; int main(){ }