个人感觉,动态开点线段树,就是在普通线段树上套一个开点操作。(就是把原来的#define中的lson和rson,换一下即可)
区间加,区间询问
#include
#define int long long
using namespace std;
const int N=1e5+5;
int n,m,x,y,v,now,cnt;
int a[N],add[N*50],sum[N*50],lson[N*50],rson[N*50];
inline void pushdown(int k,int l,int r,int mid)
{
if (add[k])
{
add[lson[k]]+=add[k];
sum[lson[k]]+=(mid-l+1)*add[k];
add[rson[k]]+=add[k];
sum[rson[k]]+=(r-(mid+1)+1)*add[k];
add[k]=0;
}
}
void build(int k,int l,int r)
{
if (l==r) {sum[k]=a[l]; return;}
if (!lson[k]) lson[k]=++cnt;
if (!rson[k]) rson[k]=++cnt;
int mid=l+r>>1;
build(lson[k],l,mid);
build(rson[k],mid+1,r);
sum[k]=sum[lson[k]]+sum[rson[k]];
}
void change(int k,int l,int r,int qx,int qy,int v)
{
if (qx<=l && r<=qy)
{
add[k]+=v;
sum[k]+=(r-l+1)*v;
return;
}
if (!lson[k]) lson[k]=++cnt;
if (!rson[k]) rson[k]=++cnt;
int mid=l+r>>1;
pushdown(k,l,r,mid);
if (qx<=mid) change(lson[k],l,mid,qx,qy,v);
if (mid<qy) change(rson[k],mid+1,r,qx,qy,v);
sum[k]=sum[lson[k]]+sum[rson[k]];
}
int query(int k,int l,int r,int qx,int qy)
{
if (qx<=l && r<=qy) return sum[k];
if (!lson[k]) lson[k]=++cnt;
if (!rson[k]) rson[k]=++cnt;
int mid=l+r>>1;
pushdown(k,l,r,mid);
int ans=0;
if (qx<=mid) ans+=query(lson[k],l,mid,qx,qy);
if (mid<y) ans+=query(rson[k],mid+1,r,qx,qy);
return ans;
}
signed main(){
scanf("%lld%lld",&n,&m);
cnt=1;
for (register int i=1; i<=n; ++i) scanf("%lld",&a[i]);
build(1,1,n);
for (register int i=1; i<=m; ++i)
{
scanf("%lld",&now);
if (now==1)
{
scanf("%lld%lld%lld",&x,&y,&v);
change(1,1,n,x,y,v);
}
else
{
scanf("%lld%lld",&x,&y);
printf("%lld\n",query(1,1,n,x,y));
}
}
return 0;
}
区间赋值,区间询问
#include
using namespace std;
const int N=3e5+5;
int n,q,cnt,l,r,v;
int sum[N*50],tag[N*50],lson[N*50],rson[N*50];
inline void pushdown(int k,int l,int r,int mid)
{
if (~tag[k])
{
sum[lson[k]]=(mid-l+1)*tag[k];
sum[rson[k]]=(r-(mid+1)+1)*tag[k];
tag[lson[k]]=tag[rson[k]]=tag[k];
tag[k]=-1;
}
}
void change(int k,int l,int r,int qx,int qy,int v)
{
if (qx<=l && r<=qy)
{
tag[k]=v;
sum[k]=(r-l+1)*v;
return;
}
if (!lson[k]) lson[k]=++cnt;
if (!rson[k]) rson[k]=++cnt;
int mid=l+r>>1;
pushdown(k,l,r,mid);
if (qx<=mid) change(lson[k],l,mid,qx,qy,v);
if (mid<qy) change(rson[k],mid+1,r,qx,qy,v);
sum[k]=sum[lson[k]]+sum[rson[k]];
}
int main(){
memset(tag,-1,sizeof(tag));
scanf("%d",&n);
scanf("%d",&q);
cnt=1;
while (q--)
{
scanf("%d%d%d",&l,&r,&v);
v&=1;
if (l>r) swap(l,r);
change(1,1,n,l,r,v);
printf("%d\n",n-sum[1]);
}
return 0;
}
推荐一道模板题:区间赋值+区间询问