各种状况。。。。考试的时候老师给了我们这一道题然后画了一个上午来码
调了一天后来发现是平衡树的rank打错了。。。。
还是那句话人傻没办法
这一题和CTSC那一题很像
我是直接暴力树链剖分+线段树套spaly。。。
然后发现时间垫底。。。。。
#include<cstdio>
#include<cstring>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int Pr_con,Pra[400001];
int print(int times,int a)
{
int i;
for(i=1;i<=times;i++)
Pra[++Pr_con]=a;
sort(Pra+1,Pra+1+Pr_con);
for(i=1;i<=Pr_con;i++)
printf("%d ",Pra[Pr_con-i+1]);
// printf("%d ",a);
puts("");
}
char c;
inline void read(int &a)
{
a=0;do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
struct Node
{
Node *f,*lc,*rc;int size,data,rank;
inline bool l(){return f->lc==this; }
};
const
int MAXN=5000000;
Node S [MAXN+1];
Node*Sta[MAXN+2];
int con;
Node *empty;
inline void Begin()
{
empty=new Node;
empty->lc=empty->rc=empty;
empty->size=0;
for(con=0;con<=MAXN;con++)
Sta[con]=S+con;
con--;
}
inline void Era(Node *a)
{Sta[++con]=a;}
inline Node *New_Node()
{Node *res=Sta[con--];res->lc=empty;res->rc=empty;res->size=1,res->rank=1;res->f=res;return res;}
inline void pushdown(Node *a)
{a->size=a->lc->size+a->rc->size+1;a->rank=a->lc->size+1;}
inline void LC(Node *a)
{
Node *now;
if(a->f->f==a->f)
now=a;
else if(a->f->l())
a->f->f->lc=a,now=a->f->f;
else
a->f->f->rc=a,now=a->f->f;
a->rc->f=a->f;
a->f->lc=a->rc;
a->rc=a->f;
a->f->f=a;
a->f=now;
pushdown(a->rc),pushdown(a);
}
inline void RC(Node *a)
{
Node *now;
if(a->f->f==a->f)
now=a;
else if(a->f->l())
a->f->f->lc=a,now=a->f->f;
else
a->f->f->rc=a,now=a->f->f;
a->lc->f=a->f;
a->f->rc=a->lc;
a->lc=a->f;
a->f->f=a;
a->f=now;
pushdown(a->lc),pushdown(a);
}
inline void Change(Node *a)
{a->l()?LC(a):RC(a);}
inline void Twice_Change(Node *a)
{a->f->l()==a->l()?Change(a->f):Change(a);Change(a);}
inline void Rotato(Node *a)
{
while(a->f->f!=a->f)
Twice_Change(a);
while(a->f!=a)Change(a);
}
Node *insert(Node *now,Node *a)
{
now->size+=1;
if(a->data>now->data)
if(now->lc==empty)
{
a->rank+=1;
a->f=now;now->lc=a;
Rotato(a);
return a;
}
else return a->rank+=1,insert(now->lc,a);
else if(now->rc==empty)
return a->f=now,now->rc=a,Rotato(a),a;
else insert(now->rc,a);
}
int t;
int find_rank(Node *now,int data)//找有多少比他小的
{
t++;
int res=0;
if(now==empty)return 0;
if(data>now->data)
return find_rank(now->lc,data);
if(data==now->data)
return res=find_rank(now->lc,data),res==0?now->rank-1:res;
else
res+=now->rank,res+=find_rank(now->rc,data);
return res;
}
Node *find(Node *now,int data)
{
if(now==empty)return empty;
if(data>now->data)
return find(now->lc,data);
if(data==now->data)
return now;
return find(now->rc,data);
}
inline Node *del(Node *now,int data)
{
Node *a=find(now,data);
Rotato(a);
Node *res;
if(a->lc!=empty)
res=a->lc,LC(a->lc);
else if(a->rc!=empty)
res=a->rc,RC(a->rc);
else
res=empty;
if(res==empty)
{
Era(a);
return res;
}
while(a->lc!=empty||a->rc!=empty)
(a->lc==empty)?
RC(a->rc):LC(a->lc);
res=a->f;
(a->l()?a->f->lc:a->f->rc)=empty;
Era(a);
pushdown(res);
Rotato(res);
return res;
}
inline void Print(Node *now,int data)
{
if(now==empty)return ;
if(data<now->data)
Print(now->lc,data),Pra[++Pr_con]=now->data,Print(now->rc,data);
else Print(now->lc,data);
}
//spaly
struct Segement
{
Node *root;
int l,r;
}Segement_Tree[1000001];
inline void Segement_Build(int place,int l,int r)
{
Segement_Tree[place].root=empty;
Segement_Tree[place].l=l;
Segement_Tree[place].r=r;
if(l^r)
{
Segement_Build(place<<1,l,(l+r)>>1);
Segement_Build(place<<1|1,((l+r)>>1)+1,r);
}
}
int Segement_Query_Rank(int place,int l,int r,int data)
{
if(Segement_Tree[place].l>=l&&Segement_Tree[place].r<=r)
return find_rank(Segement_Tree[place].root,data);
int res=0;
if(Segement_Tree[place].l^Segement_Tree[place].r)
{if(l<=Segement_Tree[place<<1].r)
res+=Segement_Query_Rank(place<<1,l,r,data);
if(r>=Segement_Tree[place<<1|1].l)
res+=Segement_Query_Rank(place<<1|1,l,r,data);
}return res;
}
void Segement_Del(int place,int l,int data)
{
Segement_Tree[place].root=del(Segement_Tree[place].root,data);
if(Segement_Tree[place].l^Segement_Tree[place].r)
{
if(l<=Segement_Tree[place<<1].r)
Segement_Del(place<<1,l,data);
else Segement_Del(place<<1|1,l,data);
}
}
void Segement_Add(int place,int l,int data)
{
Node *W=New_Node();
W->data=data;
if(Segement_Tree[place].root==empty)
{
W->rank=1,W->size=1;
Segement_Tree[place].root=W;
}
else Segement_Tree[place].root=insert(Segement_Tree[place].root,W);
if(Segement_Tree[place].l^Segement_Tree[place].r)
{
if(l<=Segement_Tree[place<<1].r)
Segement_Add(place<<1,l,data);
else Segement_Add(place<<1|1,l,data);
}
}
void Segement_Print(int place,int l,int r,int data)
{
if(Segement_Tree[place].l>=l&&Segement_Tree[place].r<=r)
{ Print(Segement_Tree[place].root,data);return ;}
if(l<=Segement_Tree[place<<1].r)
Segement_Print(place<<1,l,r,data);
if(r>=Segement_Tree[place<<1|1].l)
Segement_Print(place<<1|1,l,r,data);
}
//Segement
const
int MAX_City=40000;
struct Chain
{
Chain *next;
int u;
}*Head[MAX_City+1];
inline void Add_Side(int a,int b)
{Chain *tp=new Chain;tp->next=Head[a];tp->u=b; Head[a]=tp;}
int Heavy_Son[MAX_City+1],Heavy_Chain_Begin[MAX_City+1],Heavy_Chain_End[MAX_City+1];
int Heavy_Chain_Place[MAX_City+1],Heavy_Chain_Node[MAX_City+1];
int Chain_Con,F[MAX_City+1];
int Size[MAX_City+1],Deep[MAX_City+1];
void DFS(int u,int f)
{
F[u]=f;
Heavy_Son[u]=0;
Deep[u]=Deep[f]+1;
Size[u]=1;
for(Chain *tp=Head[u];tp;tp=tp->next)
if(tp->u!=f)
{
DFS(tp->u,u);
Size[u]+=Size[tp->u];
if(Size[Heavy_Son[u]]<Size[tp->u])
Heavy_Son[u]=tp->u;
}
}
void DFS2(int u,int f,int Begin)
{
Heavy_Chain_Begin[u]=Begin;
Heavy_Chain_Place[u]=++Chain_Con;
Heavy_Chain_Node[Chain_Con]=u;
if(Heavy_Son[u]==0)
return;
DFS2(Heavy_Son[u],u,Begin);
for(Chain *tp=Head[u];tp;tp=tp->next)
if(Heavy_Son[u]!=tp->u&&tp->u!=f)
DFS2(tp->u,u,Chain_Con+1);
Heavy_Chain_End[u]=Chain_Con;
}
int Rank_To_LCA(int x,int y,int data)
{
int res=0;
while(Heavy_Chain_Begin[x]!=Heavy_Chain_Begin[y])
{
if(Deep[Heavy_Chain_Node[Heavy_Chain_Begin[x]]]>Deep[Heavy_Chain_Node[Heavy_Chain_Begin[y]]])
res+=Segement_Query_Rank(1,Heavy_Chain_Begin[x],Heavy_Chain_Place[x],data),
x=F[Heavy_Chain_Node[Heavy_Chain_Begin[x]]];
else res+=Segement_Query_Rank(1,Heavy_Chain_Begin[y],Heavy_Chain_Place[y],data),
y=F[Heavy_Chain_Node[Heavy_Chain_Begin[y]]];
}
res+=Segement_Query_Rank(1,min(Heavy_Chain_Place[x],Heavy_Chain_Place[y]),max(Heavy_Chain_Place[x],Heavy_Chain_Place[y]),data);
// res+=Segement_Query_Rank(1,Heavy_Chain_Place[x],Heavy_Chain_Place[x],data);
return res;
}
void Print_To_LCA(int x,int y,int data)
{
Pr_con=0;
while(Heavy_Chain_Begin[x]!=Heavy_Chain_Begin[y])
{
if(Deep[Heavy_Chain_Node[Heavy_Chain_Begin[x]]]>Deep[Heavy_Chain_Node[Heavy_Chain_Begin[y]]])
Segement_Print(1,Heavy_Chain_Begin[x],Heavy_Chain_Place[x],data),
x=F[Heavy_Chain_Node[Heavy_Chain_Begin[x]]];
else Segement_Print(1,Heavy_Chain_Begin[y],Heavy_Chain_Place[y],data),
y=F[Heavy_Chain_Node[Heavy_Chain_Begin[y]]];
}
//Segement_Print(1,Heavy_Chain_Place[x],Heavy_Chain_Place[x],data);
Segement_Print(1,min(Heavy_Chain_Place[x],Heavy_Chain_Place[y]),max(Heavy_Chain_Place[x],Heavy_Chain_Place[y]),data);
}
int K,Q;
const
int INF=1001;
void Div(int x,int y)
{
int tp;
if((tp=Rank_To_LCA(x,y,0))==0)
{
puts("-1");
return ;
}
else if(tp<=K)
{Print_To_LCA(x,y,0),print(0,0);return;}
int mid,l=0,r=INF;
while(l<r)
{
mid=(l+r)>>1;
tp=Rank_To_LCA(x,y,mid);
if(tp>=K)
l=mid+1;
else
r=mid;
}
int tp2=Rank_To_LCA(x,y,r);
Print_To_LCA(x,y,r),print(K-tp2,r);
/*if(l^r)
{
tp=Rank_To_LCA(x,y,r);
if(tp<K)
Print_To_LCA(x,y,r),print(K-tp,r);
else
Print_To_LCA(x,y,l),print(K-tp2,l);
}
else
Print_To_LCA(x,y,l),print(K-tp2,l);
*/
}
//Heavy_Chain_Div
const
int Max_Knights=MAX_City;
int Force[Max_Knights+1],Place[Max_Knights+1];
int n,m;
int main()
{
int i,j,k;
Begin();
read(n);
for(i=2;i<=n;i++)
read(j),read(k),Add_Side(j,k),Add_Side(k,j);
DFS(1,1);
DFS2(1,1,1);
Segement_Build(1,1,n);
read(m);
for(i=1;i<=m;i++)
read(Force[i]),read(Place[i]),
Segement_Add(1,Heavy_Chain_Place[Place[i]],Force[i]);
read(Q),read(K);
while(Q--)
{
int T;
read(T);
if(T==1)
{
int x,y;
read(x),read(y);
Div(x,y);
}
if(T==2)
{
int x,y;
read(x),read(y);
Segement_Del(1,Heavy_Chain_Place[Place[x]],Force[x]);
Place[x]=y;
Segement_Add(1,Heavy_Chain_Place[Place[x]],Force[x]);
}
if(T==3)
{
int x,y;
read(x),read(y);
Segement_Del(1,Heavy_Chain_Place[Place[x]],Force[x]);
Force[x]=y;
Segement_Add(1,Heavy_Chain_Place[Place[x]],Force[x]);
}
}
return 0;
}