可持久化线段树
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
{{{
///sr函数支持单点修改
///red函数支持区间查询
///单点操作可以写成非递归while形式,加快速度
struct btree{
btree *o[2];
int cnt;
LL d;
}tbt[maxn*50],tnull; int tpo;
btree *newnode()
{
btree *p=&tbt[tpo++];
*p=tnull;
return p;
}
btree *sr(btree *t,int l,int r,int x,int v,int d)
{
btree *p=newnode();
if (t) *p=*t;
p->cnt+=v; p->d+=d;
if (l==r) return p;
int mid=l+r>>1;
if (x<=mid) p->o[0]=sr(p->o[0],l,mid,x,v,d);
else p->o[1]=sr(p->o[1],mid+1,r,x,v,d);
return p;
}
int red(btree *t,int l,int r,int ll,int rr)
{
if (!t) return 0;
if (ll<=l&&r<=rr) return t->cnt;
int mid=l+r>>1,ret=0;
if (ll<=mid) ret+=red(t->o[0],l,mid,ll,rr);
if (rr>mid) ret+=red(t->o[1],mid+1,r,ll,rr);
return ret;
}
}}}
///sr函数支持单点修改
///red函数支持区间查询
///单点操作可以写成非递归while形式,加快速度
struct btree{
btree *o[2];
int cnt;
LL d;
}tbt[maxn*50],tnull; int tpo;
btree *newnode()
{
btree *p=&tbt[tpo++];
*p=tnull;
return p;
}
btree *sr(btree *t,int l,int r,int x,int v,int d)
{
btree *p=newnode();
if (t) *p=*t;
p->cnt+=v; p->d+=d;
if (l==r) return p;
int mid=l+r>>1;
if (x<=mid) p->o[0]=sr(p->o[0],l,mid,x,v,d);
else p->o[1]=sr(p->o[1],mid+1,r,x,v,d);
return p;
}
int red(btree *t,int l,int r,int ll,int rr)
{
if (!t) return 0;
if (ll<=l&&r<=rr) return t->cnt;
int mid=l+r>>1,ret=0;
if (ll<=mid) ret+=red(t->o[0],l,mid,ll,rr);
if (rr>mid) ret+=red(t->o[1],mid+1,r,ll,rr);
return ret;
}