树套树裸题,留个版
(树状数组套平衡树)
#include
#define ll long long
#define INF 1000000000
#define mp make_pair
#define clr(x) memset(x,0,sizeof(x))
using namespace std;
inline int read()
{
register int ret=0,c=getchar();
while(!isdigit(c))c=getchar();
while(isdigit(c))ret=ret*10+c-'0',c=getchar();
return ret;
}
#define M 50005
struct tree2
{
tree2 *son[2],*fa;
int num,siz;
ll sum;
}*root[M],dizhi[M<<5],*null;
#define lson son[0]
#define rson son[1]
#define key rson->lson
int t,a[M],p[M],n,m;
void pushup(tree2 *tree)
{
tree->siz=tree->lson->siz+tree->rson->siz+1;
tree->sum=tree->lson->sum+tree->rson->sum+a[tree->num];
}
void rotate(tree2 *tree,int x)
{
tree2 *fa=tree->fa;
fa->son[x^1]=tree->son[x];
if(tree->son[x]!=null)tree->son[x]->fa=fa;
if(fa->fa!=null)fa->fa->son[fa->fa->son[1]==fa]=tree;
tree->fa=fa->fa;
fa->fa=tree;
tree->son[x]=fa;
pushup(fa);
}
void splay(tree2 *tree,tree2 *goal,int x)
{
if(tree==goal)return ;
while(tree->fa!=goal)
{
tree2 *fa=tree->fa,*gfa=fa->fa;
if(gfa==goal)
{
rotate(tree,fa->son[0]==tree);
break;
}
int x=gfa->son[1]==fa;
if(x==(fa->son[1]==tree))
{
rotate(fa,x^1);
rotate(tree,x^1);
}
else
{
rotate(tree,x);
rotate(tree,x^1);
}
}
pushup(tree);
if(goal==null)root[x]=tree;
}
void insert(tree2 *&tree,int x,int rt)
{
if(tree==NULL)
{
tree=&dizhi[t++];tree->fa=null;tree->siz=1;tree->lson=tree->rson=null;
return ;
}
tree2 *fa;
int k;
while(!((tree==NULL||tree==null)))
if(x>tree->num)fa=tree,k=1,tree=tree->rson;
else fa=tree,k=0,tree=tree->lson;
tree=&dizhi[t++];
tree->fa=fa;
fa->son[k]=tree;
tree->lson=tree->rson=null;
tree->sum=a[x];
tree->num=x;
tree->siz=1;
splay(tree,null,rt);
return ;
}
tree2 *find(tree2 *tree,int x)
{
while(tree->num!=x)
if(x>tree->num)tree=tree->rson;
else tree=tree->lson;
return tree;
}
tree2 *find_pre(int x,int pos)
{
tree2 *ret=null,*tree=root[x];
while(tree!=null)
{
if(tree->numnum>ret->num))ret=tree;
if(tree->num>=pos)tree=tree->lson;
else tree=tree->rson;
}
return ret;
}
tree2 *find_suf(int x,int pos)
{
tree2 *ret=null,*tree=root[x];
while(tree!=null)
{
if(tree->num>pos&&(ret==null||tree->numnum))ret=tree;
if(tree->num<=pos)tree=tree->rson;
else tree=tree->lson;
}
return ret;
}
ll query_num(int x,int l,int r)
{
if(root[x]==NULL)return 0;
splay(find_pre(x,l),null,x);
splay(find_suf(x,r),root[x],x);
return root[x]->key->sum;
}
void del(int rt,int x)
{
tree2 *tree=root[rt];
while(tree->num!=x)
tree=tree->son[x>tree->num];
tree2 *fa=tree->fa;
int d=fa->rson==tree;
if(tree->lson==null)
if(tree->rson==null)
fa->son[d]=null;
else fa->son[d]=tree->rson,tree->rson->fa=fa;
else
if(tree->rson==null)
fa->son[d]=tree->lson,tree->lson->fa=fa;
else
{
fa->son[d]=tree->lson,tree->lson->fa=fa;
tree2 *temp=tree->lson;
while(temp->rson!=null)temp=temp->rson;
tree->rson->fa=temp;
temp->rson=tree->rson;
pushup(temp);
splay(temp,null,rt);
return ;
}
if(fa==null)return ;
pushup(fa);
splay(fa,null,rt);
}
#define lowbit(x) (x&(-x))
void add(int x,int pos)
{
x++;
for(int i=x;i<=n;i+=lowbit(i))
insert(root[i],pos,i);
}
void delet(int x,int pos)
{
x++;
for(int i=x;i<=n;i+=lowbit(i))
del(i,pos);
}
ll query(int x,int l,int r)
{
// x++;
ll ret=0 ;
for(int i=x;i;i-=lowbit(i))
ret+=query_num(i,l,r);
return ret;
}
setint ,int> >S;
int main()
{
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
null=&dizhi[t++];
n=read();
for(int i=1;i<=n;i++)
{
insert(root[i],0,i);
insert(root[i],n+1,i);
}
for(int i=1;i<=n;i++)
{
a[i]=read();
setint ,int> >::iterator temp=S.upper_bound(mp(a[i],i));
if(temp!=S.begin())
{
temp--;
if(temp->first==a[i])p[i]=temp->second;
else p[i]=0;
}
else p[i]=0;
add(p[i],i);
S.insert(mp(a[i],i));
}
m=read();
for(int i=1;i<=m;i++)
{
char c=getchar();
int x=read(),y=read();
if(c=='Q')printf("%lld\n",query(x,x,y));
else
{
setint ,int> >::iterator temp=S.upper_bound(mp(a[x],x));
if(temp!=S.end()&&temp->first==a[x])
{
delet(x,temp->second);
p[temp->second]=p[x];
add(p[x],temp->second);
}
S.erase(mp(a[x],x));
delet(p[x],x);
a[x]=y;
temp=S.upper_bound(mp(a[x],x));
if(temp!=S.end()&&temp->first==a[x])
{
delet(p[temp->second],temp->second);
p[temp->second]=x;
add(x,temp->second);
}
if(temp==S.begin())p[x]=0;
else
{
temp--;
if(temp->first==a[x])p[x]=temp->second;
else p[x]=0;
}
add(p[x],x);
S.insert(mp(a[x],x));
}
}
return 0;
}