【Codeforces】【Coder-Strike 2014 - Finals】【E Cup Trick】【题解】

题意:

n个杯子从1-n标号,m个操作,x y表示当前第y的杯子上的数是x,然后把它放在队首,问字典序最小的初始状态

平衡树模拟即可

Code:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<climits>
#include<cstdlib>
#define X first
#define Y second
#define mp make_pair
using namespace std;
typedef pair<int,pair<int,int> > pii;
int rnd(){
	static int KEY=12345678;
	return KEY+=KEY<<2|1;
}
int n,m;
int vis[1000001];
int top=0;
int v[1000001];
int anss[1000001];
void print(pii x){
	printf("X:%d   Y.X:%d   Y.Y:%d \n",
			x.X,x.Y.X,x.Y.Y);
}
struct Treap{
	struct node{
		pii val;
		int key,size;
		node *c[2];
		node(pii _val,node *C){
			val=_val;key=rnd();
			c[0]=c[1]=C;size=1;
		}
		void rz(){
			size=c[0]->size+c[1]->size+1;
		}
	};	
	node *root,*Null;
	Treap(){
		Null=new node(pii(0,mp(0,0)),0);
		Null->size=0;Null->key=INT_MAX;
		Null->c[0]=Null->c[1]=Null;
		root=Null;
	}
    void rot(node *&t,bool d){  
        node *p=t->c[d];  
        t->c[d]=p->c[!d];  
        p->c[!d]=t;  
        t->rz();p->rz();  
        t=p;  
    }  
	void _insert(node *&t,pii x){
		if(t==Null){
			t=new node(x,Null);
			return;
		}
		bool d=x>t->val;
		_insert(t->c[d],x);
		if(t->c[d]->key<t->key)
			rot(t,d);
		else
			t->rz();
	}
	void _del(node *&t,pii x){
		if(t==Null)return;
		if(t->val==x){
			bool d=t->c[0]->key>t->c[1]->key;
			if(t->c[d]==Null){
				delete t;
				t=Null;
				return;
			}
			rot(t,d);
			_del(t->c[!d],x);
		}else{
			bool d=x>t->val;
			_del(t->c[d],x);
		}
		t->rz();
	}
	pii _kth(node *&t,int x){
		int r=t->c[0]->size;
		if(x==r)return t->val;
		if(x<r)return _kth(t->c[0],x);
		return _kth(t->c[1],x-r-1);
	}
	void insert(pii x){
		_insert(root,x);
	}
	void del(pii x){
		_del(root,x);
	}
	pii kth(int x){
		return _kth(root,x);
	}
//	void _run(node *&t){
//		if(t->c[0]!=Null)
//		_run(t->c[0]);
//		if(t->c[1]!=Null)	
//		_run(t->c[1]);
//		anss[t->val.Y]=t->val.X;
//		v[t->val.X]=1;
//	}
//	void run(){
//		_run(root);
//	}
	void _deb(node *&t){
		print(t->val);
		printf("L:");print(t->c[0]->val);
		printf("R:");print(t->c[1]->val);
		if(t->c[0]!=Null)
		_deb(t->c[0]);
		if(t->c[1]!=Null)
		_deb(t->c[1]);
	}
	void deb(){
		_deb(root);
	}
	int size(){
		return root->size;
	}
	pii Min(){
		node *p=root;
		while(p->c[0]!=Null)p=p->c[0];
		return p->val;
	}
}T;
void Run(){
	anss[0]=0;
	while(T.size()){
		pii k=T.Min();
		anss[k.Y.X]=k.Y.Y;
		if(~k.Y.Y)v[k.Y.Y]=1;
		T.del(k);
	}
}
int main(){
 	srand(10086);
	scanf("%d%d",&n,&m);
	
	for(int i=1;i<=n;i++)T.insert(pii(i,mp(i,-1)));
	//T.deb();
	
	for(int i=1;i<=m;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		pii k=T.kth(y-1);
		if(k.Y.Y==-1){
			if(vis[x]){puts("-1");return 0;}
			vis[x]=1;
		}else{
			if(k.Y.Y!=x){puts("-1");return 0;}
		}
		T.insert(pii(top--,mp(k.Y.X,x)));
		T.del(k);
		//T.deb();
	}
	
	
	
	Run();
	int p=0;
	for(int i=1;i<=n;i++){
		if(~anss[i])
			printf("%d ",anss[i]);
		else{
			p++;
			while(v[p])p++;
			printf("%d ",p);
		}
	}
	return 0;
}


你可能感兴趣的:(codeforces,省选)