vjudge: spoj--to the moon(主席树区间修改)

题目大意:

       题目大意:给定一些数字,有以下几个操作

       a、[L,R]区间的数字变化D的数值。并且时间向前推进

       b、询问某个时间的[L,R]区间的数字之和,这不花费时间

       c、回到X时间。

 

 

可持久话线段树裸题。

 

其实区间修改就体现了,只要主席树更新的节点,就要重建。

就本题而言,区间加我可以搞成标记永久化,防止pushdown新建太多的节点,感觉尽量不要通过pushdown加太多节点,想办法搞成标记永久化

 

#include
#include
#include
#include
#include
#include
using namespace std;
const int N=100005;
typedef long long ll;

struct aa
{
	int lc,rc,l,r;
	ll add,sum;
	int len(){return r-l+1;}
}a[N*4*200];

int n,m,rt[N],time,tot;

void build(int &u,int l,int r)
{
	u=++tot;
	a[u].l=l,a[u].r=r;
	if (l==r) {scanf("%lld",&a[u].sum);return ;}
	int mid=(l+r)>>1;
	build(a[u].lc,l,mid);
	build(a[u].rc,mid+1,r);
	a[u].sum=a[a[u].lc].sum+a[a[u].rc].sum;
}
void insert(int &now,int old,int l,int r,ll d)
{
	now=++tot;
	a[now]=a[old];
	if (a[old].l==l&&a[old].r==r)
	{
		a[now].add+=d;
		return;
	}
	a[now].sum+=d*(r-l+1);
	int mid=(a[now].l+a[now].r)>>1;
	if (r<=mid) insert(a[now].lc,a[old].lc,l,r,d);
	else if (mid>1;
	if (r<=mid) return tmp+query(a[u].lc,l,r);
	else if (mid


 

 

 

你可能感兴趣的:(主席树)