• 【BZOJ1056】[HAOI2008]排名系统(Splay)


    【BZOJ1056】[HAOI2008]排名系统(Splay)

    题面

    BZOJ
    洛谷

    题解

    (Splay)随便维护一下就好了,至于名字什么的,我懒得手写哈希表了,直接哈希之后拿(map)压。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<map>
    using namespace std;
    #define ll long long
    #define ull unsigned long long
    #define MAX 250500
    #define ls (t[x].ch[0])
    #define rs (t[x].ch[1])
    #define inf 2000000000
    const int base=233;
    inline int read()
    {
    	int x=0;bool t=false;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=true,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return t?-x:x;
    }
    map<ull,int> M;
    char name[MAX][20],ch[20];
    int len[MAX];
    struct Node
    {
    	int ch[2],ff;
    	int v,size;
    }t[MAX];
    int rt,n,tot;
    void pushup(int x){t[x].size=t[ls].size+t[rs].size+1;}
    void rotate(int x)
    {
    	int y=t[x].ff,z=t[y].ff;
    	int k=t[y].ch[1]==x;
    	if(z)t[z].ch[t[z].ch[1]==y]=x;t[x].ff=z;
    	t[y].ch[k]=t[x].ch[k^1];t[t[x].ch[k^1]].ff=y;
    	t[x].ch[k^1]=y;t[y].ff=x;
    	pushup(y);pushup(x);
    }
    void Splay(int x,int goal)
    {
    	while(t[x].ff!=goal)
    	{
    		int y=t[x].ff,z=t[y].ff;
    		if(z!=goal)
    			(t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);
    		rotate(x);
    	}
    	if(!goal)rt=x;
    }
    void insert(int u,int id)
    {
    	int x=rt;
    	while(233)
    	{
    		if(!t[x].ch[u>t[x].v])
    		{
    			t[id].ff=x;t[id].v=u;t[id].size=1;
    			t[x].ch[u>t[x].v]=id;
    			Splay(id,0);
    			break;
    		}
    		else x=t[x].ch[u>t[x].v];
    	}
    }
    int Kth(int K)
    {
    	int x=rt;
    	while(233)
    	{
    		if(t[ls].size+1==K)return x;
    		else if(t[ls].size>=K)x=ls;
    		else K-=t[ls].size+1,x=rs;
    	}
    }
    void Del(int x)
    {
    	Splay(x,0);int rk=t[ls].size;
    	int l=Kth(rk),r=Kth(rk+2);
    	Splay(l,0);Splay(r,l);t[r].ch[0]=0;
    	pushup(r);pushup(l);
    	t[x].ff=t[x].size=t[x].v=0;
    }
    int getnum(char *s)
    {
    	int l=strlen(s+1),ret=0;
    	for(int i=1;i<=l;++i)ret=ret*10+s[i]-48;
    	return ret;
    }
    ull gethash(char *s)
    {
    	int l=strlen(s+1);ull h=0;
    	for(int i=1;i<=l;++i)h=h*base+s[i];
    	return h;
    }
    void Output(int x,int &sum)
    {
    	if(sum>=10)return;
    	if(rs)Output(rs,sum);
    	if(sum>=10)return;
    	if(x>2)
    	{
    		++sum;
    		for(int i=1;i<len[x];++i)
    			putchar(name[x][i]);
    		putchar(' ');
    	}
    	if(ls)Output(ls,sum);
    }
    int main()
    {
    	n=read();
    	insert(-inf,++tot);insert(inf,++tot);
    	while(n--)
    	{
    		scanf("%s",ch);
    		if(ch[0]=='+')
    		{
    			ull h=gethash(ch);int sco=read(),id;
    			if(M[h])id=M[h],Del(id),insert(sco,id);
    			else
    			{
    				insert(sco,M[h]=id=++tot);
    				for(int i=1,l=strlen(ch);i<l;++i)name[tot][i]=ch[i];
    				len[tot]=strlen(ch);
    			}
    		}
    		else if(ch[1]>='0'&&ch[1]<='9')
    		{
    			int rk=getnum(ch);
    			int l=Kth(tot-rk+1);
    			Splay(l,0);int sum=0;
    			Output(t[l].ch[0],sum);puts("");
    		}
    		else
    		{
    			ull h=gethash(ch);
    			int x=M[h];Splay(x,0);
    			printf("%d
    ",t[rs].size);
    		}
    		if(n%200==0)Splay(rand()%tot+1,0);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Linux图形界面从登录列表中隐藏用户和开机自动登录
    VMware Workstation报错 : 另一个正在运行的VMware进程可能正在使用配置文件
    Vim命令总结
    Linux常用命令总结
    Oracle使用中的常规操作总结
    Oracle分页查询和SQL server分页查询总结
    Oracle学习总结
    Resharper2019 1.2破解教程
    C#实现RSA加密解密
    windows上git clone命令速度过慢问题的解决
  • 原文地址:https://www.cnblogs.com/cjyyb/p/9737178.html
Copyright © 2020-2023  润新知