bzoj4336: BJOI2015 骑士的旅行

各种状况。。。。考试的时候老师给了我们这一道题然后画了一个上午来码

调了一天后来发现是平衡树的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;
}



你可能感兴趣的:(bzoj)