线段树的板子
shadowice1984
2018-04-04 20:50:02
这里是shadowice自用的板子
然后会有一些毒瘤压行的行为方便考试的时候自己写,就酱。
tips:请采用假标记写法,处理多关键标记的时候非常好使,这里以区间加区间乘为参考
```C
#include<cstdio>
#include<algorithm>
using namespace std;const int N=1e5+10;typedef long long ll;const ll mod=1e9+7;
struct linetree
{
ll val[4*N];ll add[4*N];ll mult[4*N];
inline void pushdown(int p)
{
add[p<<1]=(add[p]*mult[p]+add[p<<1])%mod;
add[p<<1|1]=(add[p]*mult[p]+add[p<<1|1])%mod;
mult[p<<1]=mult[p<<1]*mult[p]%mod;
mult[p<<1|1]=mult[p<<1|1]*mult[p]%mod;
val[p<<1]=(val[p<<1]*mult[p]+add[p])%mod;
val[p<<1|1]=(val[p<<1|1]*mult[p]+add[p])%mod;
}
inline void setadd(int p,int l,int r,int dl,int dr,ll plus)
{
if(dl==l&&dr==r){val[p]=(val[p]+plus)%mod;add[p]=(add[p]+plus)%mod;return;}
int mid=(l+r)/2;pushdown(p);
if(dl<mid){setadd(p<<1,l,mid,dl,min(dr,mid),plus);}
if(mid<dr){setadd(p<<1|1,mid,r,max(dl,mid),dr,plus);}
val[p]=(val[p<<1]+val[p<<1|1])%mod;
}
inline void setmul(int p,int l,int r,int dl,int dr,ll mul)
{
if(dl==l&&dr==r){val[p]=val[p]*mul%mod;mult[p]=mult[p]*mul%mod;return;}
int mid=(l+r)/2;pushdown(p);
if(dl<mid){setmul(p<<1,l,mid,dl,min(dr,mid),mul);}
if(mid<dr){setmul(p<<1|1,mid,r,max(dl,mid),dr,mul);}
val[p]=(val[p<<1]+val[p<<1|1])%mod;
}
inline ll sum(int p,int l,int r,int dl,int dr)
{
if(dl==l&&dr==r){return val[p];}int mid=(l+r)/2;pushdown(p);ll res=0;
if(dl<mid){res=(res+sum(p<<1,l,mid,dl,min(dr,mid)))%mod;}
if(mid<dr){res=(res+sum(p<<1|1,mid,r,max(dl,mid),dr))%mod;}
return res;
}
inline void build(int p,int l,int r)
{
mul[p]=1;if(r-l==1){scanf("%lld",&val[p]);return;}int mid=(l+r)/2;
build(p<<1,l,mid);build(p<<1|1,mid,r);val[p]=(val[p<<1]+val[p<<1|1])%mod;
}
}lt;
```