记录编号 192407 评测结果 AAAAAAAAAA
题目名称 [HAOI 2008]排名系统 最终得分 100
用户昵称 Gravataryyy 是否通过 通过
代码语言 C++ 运行时间 2.476 s
提交时间 2015-10-10 20:55:35 内存使用 38.46 MiB
显示代码纯文本
#include <stdio.h>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <string>
#include <map>
#include <time.h>
 
using std::string;
 
typedef long long Long;
 
std::map<string,int> node;
 
namespace output
{
	struct node
	{
		string s;
		int n;
		Long val;
		node(string ss,int nn,Long vval)
		{
			s = ss;
			n = nn;
			val = vval;
		}
		
		node()
		{}
		
		bool operator<(const node & b)const
		{
			if(val == b.val)
				return n < b.n;
			return val < b.val;
		}
	};
	std::vector<node> vec;
	
	void output()
	{
		std::sort(vec.begin(),vec.end());
		for(int i = 0;i < vec.size();i++)
		{
			if(i == 0)
				printf("%s",vec[i].s.c_str());
			else printf(" %s",vec[i].s.c_str());
		}
		printf("\n");
	}
}

const int N = 500000;
 
namespace splay
{
	struct Int
	{
		Long val;
		int time;
		
		bool operator < (const Int & b)const
		{
			if(val == b.val)
				return time < b.time;
			return val < b.val;
		}
		
		bool operator > (const Int & b)const
		{
			if(val == b.val)
				return time > b.time;
			return val > b.val;
		}
		
		bool operator == (const Int & b)const
		{
			return val == b.val && time == b.time;
		}
		
		bool operator != (const Int & b)const
		{
			return val != b.val || time != b.time;
		}
		
		Int(Long a,int b)
		{
			val = a;
			time = b;
		}
		Int()
		{}
		
	};
	
	struct node
	{
		string name;
		Int val;
		int son[2];
		int size;
		int is_right;
		int father;
		bool lazy;
	};
	
	int tot = 0;
	node nodes[2 * N + 100];
	
	#define LC(a) nodes[a].son[0]
	#define RC(a) nodes[a].son[1]
	#define SIZE(a) nodes[a].size
	#define VAL(a) nodes[a].val
	#define TIME(a) hash::time_in[nodes[a].name]
	#define FATHER_ME(a) nodes[nodes[a].father].son[nodes[a].is_right]
	
	int root = 0;
	
	string now_name;
	int newnode(Long val,int ti)
	{
		tot++;
		nodes[tot].name = now_name;
		nodes[tot].val = Int(val,ti);
		nodes[tot].size = 1;
		return tot;
	}
	
	void updata(int d)
	{
		if(!d)
			return;
		if(nodes[d].lazy)
			SIZE(d) = SIZE(LC(d)) + SIZE(RC(d));
		else SIZE(d) = SIZE(LC(d)) + SIZE(RC(d)) + 1;
	}
	
	void add(int & d,Long val,int is_right,const int & ti,const int & fat = 0)
	{
		if(!d)
		{
			d = newnode(val,ti);
			nodes[d].is_right = is_right;
			nodes[d].father = fat;
			return;
		}
		
		if(Int(val,ti) > VAL(d))
			add(RC(d),val,1,ti,d);
		else add(LC(d),val,0,ti,d);
		
		updata(d);
	}
	
	void r_r(int f)
	{
		if(!f)
			return;
		int s = nodes[f].son[0];
		int b = nodes[s].son[1];
			 
		if(f == root)
			root = s;
		else FATHER_ME(f) = s;
		
		nodes[s].is_right = nodes[f].is_right;
		nodes[s].father = nodes[f].father;
		
		nodes[f].father = s;
		nodes[f].is_right = 1;
		nodes[s].son[1] = f;
		
		nodes[b].father = f;
		nodes[b].is_right = 0;
		nodes[f].son[0] = b;
		
		updata(f);
		updata(s);
	}
	
	void l_r(int f)
	{
		if(!f)
			return;
		int s = nodes[f].son[1];
		int b = nodes[s].son[0];
			 
		if(f == root)
			root = s;
		else FATHER_ME(f) = s;
		
		nodes[s].is_right = nodes[f].is_right;
		nodes[s].father = nodes[f].father;
		
		nodes[f].father = s;
		nodes[f].is_right = 0;
		nodes[s].son[0] = f;
		
		nodes[b].father = f;
		nodes[b].is_right = 1;
		nodes[f].son[1] = b;
		
		updata(f);
		updata(s);
	}
	
	void del(int d)
	{
		if(!d)
			return;
		nodes[d].lazy = true;
		
		updata(d);
		
		int f = nodes[d].father;
		while(f)
		{
			updata(f);
			f = nodes[f].father;
		}
	}
	
	int find_kth(int d,int k,int f = 0)
	{
		if(!d)
			return 0;
		if(nodes[d].lazy)
		{
			if(k <= SIZE(LC(d)))
				return find_kth(LC(d),k);
			return find_kth(RC(d),k - SIZE(LC(d)),d);
		}
		if(SIZE(LC(d)) == k - 1)
			return d;
		if(k <= SIZE(LC(d)))
			return find_kth(LC(d),k);
		return find_kth(RC(d),k - SIZE(LC(d)) - 1);
	}
	
	int find_num(int d,Long val,int ti)
	{
		if(!d)
			return 0;
		int sz = 0;
		Int v = Int(val,ti);
		while(nodes[d].val != v)
		{
			if(v > nodes[d].val)
			{
				sz += SIZE(LC(d)) + 1;
				if(nodes[d].lazy)
					sz--;
				d = RC(d);
			}
			else d = LC(d);
		}
		sz += SIZE(LC(d)) + 1;
		if(nodes[d].lazy)
			sz--;
		return sz;
	}
	
	void rot(int a)
	{
		if(!a)
			return;
		if(nodes[a].is_right)
			l_r(nodes[a].father);
		else r_r(nodes[a].father);
	}
	
	void splay(int a)
	{
		if(!a)
			return;
		while(a != root)
		{
			if(nodes[a].is_right != nodes[nodes[a].father].is_right)
			{
				rot(a);
				rot(a);
			}
			else 
			{
				rot(nodes[a].father);
				rot(a);
			}
		}
	}
};
 
char str[20]; 
 
int main()
{
	{
		int _q=10<<20;
		char *_p=(char*)malloc(_q)+_q;
		__asm__("movl %0, %%esp\n"::"r"(_p));
	}
	
	freopen("rank.in","r",stdin);
	freopen("rank.out","w",stdout);
	
	int n = 0;
	scanf("%d",&n);
	
	char c = 0;
	int op = 0;
	int num = 0;
	int re = 0;
	int m = 0;
	Long Lnum = 0LL;
	int tt = 0;
	string nm;
	for(int i = 0;i < n;i++)
	{
		do
		{
			c = getchar();
		}
		while(c == ' ' || c == '\n' || c == '\t');
	
		if(c == '?')
		{
			c = getchar();
			if(c >= '0' && c <= '9')
				op = 1;//给定排名问名字 
			else op = 2;//给定名字问排名 
			
			ungetc(c,stdin);
		}
		else op = 3;//改分数
		
		if(op == 1)
		{
			scanf("%d",&num);
			//continue;
			output::vec.clear();
			re = 0;
			for(int p = num;p < num + 10;p++)
			{
				if(p > splay::nodes[splay::root].size)
					break;
				if(re == 0)
					re = splay::find_kth(splay::root,p);
				else re = splay::find_kth(splay::nodes[re].son[1],1);
				splay::splay(re);
				
				output::vec.push_back(output::node(splay::nodes[re].name,splay::nodes[re].val.time,splay::nodes[re].val.val));
			}
			output::output();
		}
		else if(op == 2)
		{
			scanf("%s",str);
			//continue;
			int hh = node[string(str)];
			splay::splay(hh);
			Lnum = splay::nodes[hh].val.val;
			tt = splay::nodes[hh].val.time;
			printf("%d\n",splay::find_num(splay::root,Lnum,tt));
		}
		else
		{
			scanf("%s",str);
			std::cin>>Lnum;
			Lnum = -Lnum;
			nm = str;
			m = node[nm];
			splay::del(m);
			if(m)
				splay::splay(m);
			splay::now_name = nm;
			splay::add(splay::root,Lnum,0,i + 1);
			node[nm] = splay::tot;
			splay::splay(splay::tot);
		}
		
		//if(i % 100000 == 0)
		//	fprintf(stderr,"%d %d %d\n",i,clock(),op);
	}
	
	return 0;
}