求助动态开点线段树
查看原帖
求助动态开点线段树
565945
Azure__楼主2022/7/2 09:09

想试试用动态开点写,30pts,样例过不了。 感谢大佬帮忙。

#include<bits/stdc++.h>
#define int long long 
using namespace std;
int n,m,cnt,root;
struct node{
	int l,r,w,f;
} tree[2*100000+1];
int a[100001];
inline int read(){
	char c; int x=0,f=1; c=getchar();
	while(c<'0'||c>'9'){ if(c=='-') f=-1; c=getchar(); }
	while(c>='0'&&c<='9'){ x=(x<<3)+(x<<1)+(c^48); c=getchar(); }
	return x*f;
}
inline void push_up(int k){
	tree[k].w=tree[tree[k].l].w+tree[tree[k].r].w;
}
inline int build(){
	tree[++cnt].w=0;
	tree[cnt].f=0;
	tree[cnt].l=0;
	tree[cnt].r=0;
	return cnt;
}
inline void push_down(int k,int l,int r){
	tree[tree[k].l].w+=(tree[tree[k].l].r-tree[tree[k].l].l+1)*tree[k].f;
	tree[tree[k].r].w+=(tree[tree[k].r].r-tree[tree[k].r].l+1)*tree[k].f;
	tree[tree[k].l].f+=tree[k].f;
	tree[tree[k].r].f+=tree[k].f;
	tree[k].f=0;
}
inline void insert(int l,int r,int k,int ind,int x){
	if(l==r){
		tree[k].w=x; return;
	}
	int mid=(l+r)>>1;
	if(ind<=mid){
		if(!tree[k].l) tree[k].l=build();
		insert(l,mid,tree[k].l,ind,x);
	}
	else{
		if(!tree[k].r) tree[k].r=build();
		insert(mid+1,r,tree[k].r,ind,x);
	}
	push_up(k);
}
inline int ask_interval(int k,int l,int r,int a,int b){
	if(l>=a&&r<=b){
		return tree[k].w;
	}
	if(tree[k].f) push_down(k,l,r);
	int mid=(l+r)>>1,ans=0;;
	if(a<=mid) ans+=ask_interval(tree[k].l,l,mid,a,b);
	if(b>mid) ans+=ask_interval(tree[k].r,mid+1,r,a,b);
	return ans;
}
inline void change_interval(int k,int l,int r,int a,int b,int y){
	if(l>=a&&r<=b){
		tree[k].w+=(tree[k].r-tree[k].l+1)*y;
		tree[k].f+=y;
		return ;
	}
	if(tree[k].f) push_down(k,l,r);
	int mid=(l+r)>>1;
	if(a<=mid){
		if(!tree[k].l) tree[k].l=build();
		change_interval(tree[k].l,l,mid,a,b,y);
	}
	if(b>mid) {
		if(!tree[k].r) tree[k].r=build();
		change_interval(tree[k].r,mid+1,r,a,b,y);
	}
	push_up(k);
}
signed main()
{
	n=read();
	m=read();
	root=build();
	for(int i=1;i<=n;i++){
		a[i]=read();
		insert(1,n,root,i,a[i]);
	}
	while(m--){
		int opt=read();
		if(opt==1){
			int a=read(),b=read(),y=read();
			change_interval(1,1,n,a,b,y);
		}
		if(opt==2){
			int a=read(),b=read();
			printf("%lld\n",ask_interval(1,1,n,a,b));
		}
	}
	return 0;
}
```cpp
2022/7/2 09:09
加载中...