• 洛谷P2343 宝石管理系统 splay


    网址:https://www.luogu.org/problem/P2343

    题意:

    维护一个支持$O(logn)$插入和查询第$k$大的数据结构。

    题解:

    只要是平衡树都行。这里我们使用$splay$,抄个板子即可。

    AC代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN = 1e5 + 5;
    struct Splay
    {
    	int fa[MAXN], val[MAXN], son[MAXN][2], size[MAXN], num[MAXN];
    	int sz, rt;
    	void init()
    	{
    		rt = sz = 0;
    	}
    	bool getson(int x)
    	{
    		return son[fa[x]][1] == x;
    	}
    	void con(int x, int y, int z)
    	{
    		if (x)
    			fa[x] = y;
    		if (y)
    			son[y][z] = x;
    	}
    	void up(int x)
    	{
    		if (x)
    		{
    			size[x] = num[x];
    			if (son[x][0])
    				size[x] += size[son[x][0]];
    			if (son[x][1])
    				size[x] += size[son[x][1]];
    		}
    	}
    	void rotate(int x)
    	{
    		int fx = fa[x], ffx = fa[fx];
    		int fs = getson(x), ffs = getson(fx);
    		con(son[x][fs ^ 1], fx, fs);
    		con(fx, x, fs ^ 1);
    		con(x, ffx, ffs);
    		up(fx), up(x);
    	}
    	void splay(int x, int end)
    	{
    		end = fa[end];
    		int f;
    		while (fa[x] != end)
    		{
    			f = fa[x];
    			if (fa[f] != end)
    				rotate(getson(x) == getson(f) ? f : x);
    			rotate(x);
    		}
    		if (!end)
    			rt = x;
    	}
    	int newnode(int x, int f)
    	{
    		int root = ++sz;
    		fa[root] = f;
    		son[f][x > val[f]] = root;
    		son[root][0] = son[root][1] = 0;
    		size[root] = num[root] = 1;
    		val[root] = x;
    		return root;
    	}
    	void insert(int x)
    	{
    		if (!rt)
    		{
    			rt = newnode(x, 0);
    			return;
    		}
    		int now = rt, f = 0;
    		while (1)
    		{
    			if (x == val[now])
    			{
    				++num[now];
    				up(now), up(f);
    				splay(now, rt);
    				return;
    			}
    			f = now, now = son[now][x > val[now]];
    			if (!now)
    			{
    				int tmp = newnode(x, f);
    				up(f);
    				splay(tmp, rt);
    				return;
    			}
    		}
    	}
    	int querynum(int rnk)
    	{
    		int now = rt;
    		while (1)
    		{
    			if (son[now][1] && rnk <= size[son[now][1]])
    			{
    				now = son[now][1];
    				continue;
    			}
    			if (son[now][1])
    				rnk -= size[son[now][1]];
    			if (rnk <= num[now])
    			{
    				splay(now, rt);
    				return now;
    			}
    			rnk -= num[now];
    			now = son[now][0];
    		}
    	}
    };
    Splay sp;
    
    const int MAXBUF = 1 << 20;
    char buf[1 << 20], * fh = NULL, * ft = NULL;
    inline char gc()
    {
    	if (fh == ft)
    	{
    		int l = fread(buf, 1, MAXBUF, stdin);
    		ft = (fh = buf) + l;
    	}
    	return *fh++;
    }
    
    inline int read()
    {
    	int x = 0;
    	char c = gc();
    	for (; c < '0' || c > '9'; c = gc())
    		;
    	for (; c >= '0' && c <= '9'; c = gc())
    		x = (x << 3) + (x << 1) + c - '0';
    	return x;
    }
    inline void _write(long long x)
    {
    	if (x > 9)
    		_write(x / 10);
    	putchar(x % 10 + '0');
    }
    inline void write(long long x)
    {
    	_write(x);
    	putchar('
    ');
    }
    
    
    int main()
    {
    	sp.init();
    	int n, m, a, op;
    	//scanf("%d%d", &n, &m);
    	n = read(), m = read();
    	for (int i = 0; i < n; ++i)
    	{
    		//scanf("%d", &a);
    		a = read();
    		sp.insert(a);
    	}
    	for (int i = 0; i < m; ++i)
    	{
    		//scanf("%d%d", &op, &a);
    		op = read(), a = read();
    		if (op == 1)
    			printf("%d
    ", sp.val[sp.querynum(a)]);
    		else if (op == 2)
    			sp.insert(a);
    	}
    	return 0;
    }
    
  • 相关阅读:
    PAT 甲级 1004 Counting Leaves
    C#列的一些操作
    EXT.NET 一些用法
    ext.net 所有版本
    鱼线拉力值
    CRM 总是弹出登录窗口
    台钓线组及各种绑法
    windows server 2012 r2 安装IIS失败
    [iOS]UITableView刷新
    [Linux]APUE读书笔记: 文件和目录
  • 原文地址:https://www.cnblogs.com/Aya-Uchida/p/11643054.html
Copyright © 2020-2023  润新知