各种状况。。。。考试的时候老师给了我们这一道题然后画了一个上午来码
调了一天后来发现是平衡树的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; }