线段树模版(含动态开点)
【模板】线段树 2
题目描述
如题,已知一个数列,你需要进行下面三种操作:
- 将某区间每一个数乘上 \(x\);
- 将某区间每一个数加上 \(x\);
- 求出某区间每一个数的和。
输入格式
第一行包含三个整数 \(n,q,m\),分别表示该数列数字的个数、操作的总个数和模数。
第二行包含 \(n\) 个用空格分隔的整数,其中第 \(i\) 个数字表示数列第 \(i\) 项的初始值。
接下来 \(q\) 行每行包含若干个整数,表示一个操作,具体如下:
操作 \(1\): 格式:1 x y k
含义:将区间 \([x,y]\) 内每个数乘上 \(k\)
操作 \(2\): 格式:2 x y k
含义:将区间 \([x,y]\) 内每个数加上 \(k\)
操作 \(3\): 格式:3 x y
含义:输出区间 \([x,y]\) 内每个数的和对 \(m\) 取模所得的结果
输出格式
输出包含若干行整数,即为所有操作 \(3\) 的结果。
样例 #1
样例输入 #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
提示
【数据范围】
对于 \(30\%\) 的数据:\(n \le 8\),\(q \le 10\)。
对于 \(70\%\) 的数据:\(n \le 10^3\),\(q \le 10^4\)。
对于 \(100\%\) 的数据:\(1 \le n \le 10^5\),\(1 \le q \le 10^5\)。
除样例外,\(m = 571373\)。
(数据已经过加强 ^ _ ^)
样例说明:
故输出应为 \(17\)、\(2\)(\(40 \bmod 38 = 2\))。
线段树开long long容易超时!!!
如果你样例的第二个输出是 \(32\),那么请注意你是否在 Mul
中调用了 Add
#include<bits/stdc++.h>
//#define int long long
#define ll long long
#define ull /*unsigned*/ long long
#define fd(i,a,b) for(int i=a,_i=b;i<=_i;i=-~i)
#define bd(i,a,b) for(int i=a,_i=b;i>=_i;i=~-i)
#define Db(a,b,ans) cout<<a<<';'<<b<<','<<ans<<endl
#define debug puts("-----------");
using namespace std;
const int N=1e6+509;
ll n,m,a[N],mod;
struct ST
{
struct node
{
ll l,r,add,sum,mul;
#define l(x) st[x].l
#define r(x) st[x].r
#define add(x) st[x].add
#define sum(x) st[x].sum
#define mul(x) st[x].mul
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
}st[N<<1];
inline void pushdown(int p)
{
if(add(p)==0&&mul(p)==1) return;
sum(ls(p))=(sum(ls(p))*mul(p)%mod+add(p)*(r(ls(p))-l(ls(p))+1)%mod)%mod;
sum(rs(p))=(sum(rs(p))*mul(p)%mod+add(p)*(r(rs(p))-l(rs(p))+1)%mod)%mod;
mul(ls(p))=mul(ls(p))*mul(p)%mod;
mul(rs(p))=mul(rs(p))*mul(p)%mod;
add(ls(p))=(add(ls(p))*mul(p)%mod+add(p))%mod;
add(rs(p))=(add(rs(p))*mul(p)%mod+add(p))%mod;
add(p)=0;
mul(p)=1;
}
inline void pushup(int p)
{
sum(p)=sum(ls(p))+sum(rs(p));
sum(p)%=mod;
}
void build(int p,int l,int r)
{
l(p)=l,r(p)=r;
add(p)=0,mul(p)=1;
if(l==r)
{
sum(p)=a[r];
return;
}
int mid=((r-l)>>1)+l;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
pushup(p);
}
void Add(int p,int l,int r,ll v)
{
if(l(p)>=l&&r(p)<=r)
{
add(p)=(add(p)+v)%mod;
sum(p)=(sum(p)+v*(r(p)-l(p)+1)%mod)%mod;
return;
}
pushdown(p);
int mid=((r(p)-l(p))>>1)+l(p);
if(l<=mid) Add(ls(p),l,r,v);
if(mid<r) Add(rs(p),l,r,v);
pushup(p);
}
void Mul(int p,int l,int r,ll v)
{
if(l(p)>=l&&r(p)<=r)
{
add(p)=(add(p)*v)%mod;
mul(p)=(mul(p)*v)%mod;
sum(p)=(sum(p)*v)%mod;
return;
}
pushdown(p);
int mid=((r(p)-l(p))>>1)+l(p);
if(l<=mid) Mul(ls(p),l,r,v);
if(mid<r) Mul(rs(p),l,r,v);
pushup(p);
}
ll ask(int p,int l,int r)
{
if(l(p)>=l&&r(p)<=r) return sum(p);
pushdown(p);
int mid=((r(p)-l(p))>>1)+l(p);
ll res=0;
if(l<=mid) res+=ask(ls(p),l,r)%mod;
if(mid<r) res+=ask(rs(p),l,r)%mod;
return res%mod;
}
}St;
signed main()
{
#ifdef FJ
freopen("seq.in","r",stdin);
freopen("seq.out","w",stdout);
#endif
// ios::sync_with_stdio(0);
// cin.tie(0); cout.tie(0);
scanf("%lld%lld",&n,&mod);
fd(i,1,n) scanf("%lld",&a[i]);
St.build(1,1,n);
scanf("%lld",&m);
ll op,t,g,c;
fd(i,1,m)
{
scanf("%lld",&op);
if(op==1)
{
scanf("%lld%lld%lld",&t,&g,&c);
St.Mul(1,t,g,c);
}
if(op==2)
{
scanf("%lld%lld%lld",&t,&g,&c);
St.Add(1,t,g,c);
}
if(op==3)
{
scanf("%lld%lld",&t,&g);
printf("%lld\n",St.ask(1,t,g));
}
}
return 0;
}
upd on 2024.11.28
更新动态开点版本
#include<bits/stdc++.h>
#define int long long
#define ll long long
#define fd(i,a,b) for(int i=(a);i<=(b);i=-~i)
#define bd(i,a,b) for(int i=(a);i>=(b);i=~-i)
#define db(x) cout<<"DEBUG "<<#x<<" = "<<x<<endl;
#define endl '\n'
using namespace std;
//#define SIZE (1<<20)
//char In[SIZE],Out[SIZE],*p1=In,*p2=In,*p3=Out;
//#define getchar() (p1==p2&&(p2=(p1=In)+fread(In,1,SIZE,stdin),p1==p2)?EOF:*p1++)
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+(c-48),c=getchar();}
return x*f;
}
template<typename _T>
inline void write(_T x)
{
static _T sta[35];int top=0;
if(x<0) putchar('-'),x=-x;
do{sta[top++]=x%10,x/=10;}while(x);
while(top) putchar(sta[--top]+'0');
}
const int N=1e6+509,M=1e6+509;
int mod;
int n,a[N],q;
struct node
{
int ls,rs,sum,add,mul,l,r;
node(){ls=rs=sum=add=0,mul=1;}
#define ls(p) t[p].ls
#define rs(p) t[p].rs
#define sum(p) t[p].sum
#define add(p) t[p].add
#define mul(p) t[p].mul
}t[N<<1];
int rt,tot;
inline void pushup(int p)
{
sum(p)=sum(ls(p))+sum(rs(p));
}
inline void pushdown(int p,int l,int r)
{
if(!ls(p)) ls(p)=++tot;
if(!rs(p)) rs(p)=++tot;
if(add(p)==0&&mul(p)==1) return;
int mid=(l+r)>>1;
(sum(ls(p))*=mul(p))%=mod;
(sum(rs(p))*=mul(p))%=mod;
(sum(ls(p))+=add(p)*(mid-l+1)%mod)%=mod;
(sum(rs(p))+=add(p)*(r-mid)%mod)%=mod;
(add(ls(p))*=mul(p))%=mod,(add(rs(p))*=mul(p))%=mod;
(add(ls(p))+=add(p))%=mod,(add(rs(p))+=add(p))%=mod;
(mul(ls(p))*=mul(p))%=mod,(mul(rs(p))*=mul(p))%=mod;
add(p)=0,mul(p)=1;
}
void Add(int &p,int l,int r,int L,int R,int v)
{
if(l>R||L>r) return;
if(!p) p=++tot;
if(L<=l&&r<=R)
{
(sum(p)+=v*(r-l+1)%mod)%=mod;
(add(p)+=v)%=mod;
return;
}
pushdown(p,l,r);
int mid=(r+l)>>1;
Add(ls(p),l,mid,L,R,v);
Add(rs(p),mid+1,r,L,R,v);
pushup(p);
}
void Mul(int &p,int l,int r,int L,int R,int v)
{
if(l>R||L>r) return;
if(!p) p=++tot;
if(L<=l&&r<=R)
{
(sum(p)*=v)%=mod;
(mul(p)*=v)%=mod;
(add(p)*=v)%=mod;
return;
}
pushdown(p,l,r);
int mid=(r+l)>>1;
Mul(ls(p),l,mid,L,R,v);
Mul(rs(p),mid+1,r,L,R,v);
pushup(p);
}
int Ask(int &p,int l,int r,int L,int R)
{
if(l>R||L>r) return 0;
if(!p) p=++tot;
// cerr<<"#"<<p<<' '<<l<<' '<<r<<' '<<sum(p)<<endl;
if(L<=l&&r<=R) return sum(p);
pushdown(p,l,r);
int mid=(r+l)>>1,res=0;
res+=Ask(ls(p),l,mid,L,R);
res+=Ask(rs(p),mid+1,r,L,R);
return res%mod;
}
signed main()
{
//#define FJ
#ifdef FJ
freopen(".in","r",stdin);
freopen(".out","w",stdout);
#else
// freopen("A.in","r",stdin);
// freopen("A.out","w",stdout);
#endif
//#define io
#ifdef io
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
#endif
n=read(),q=read(),mod=read();
fd(i,1,n) Add(rt,1,n,i,i,read());
while(q--)
{
int op=read(),x=read(),y=read(),k;
if(op!=3) k=read();
if(op==1) Mul(rt,1,n,x,y,k);
if(op==2) Add(rt,1,n,x,y,k);
if(op==3) printf("%lld\n",Ask(rt,1,n,x,y));
// fd(i,1,n) printf("%lld ",Ask(rt,1,n,i,i));
// puts("");
}
return 0;
}
本文来自博客园,作者:whrwlx,转载请注明原文链接:https://www.cnblogs.com/whrwlx/p/18287400