zoukankan      html  css  js  c++  java
  • [luoguP2596] [ZJOI2006]书架(splay)

    传送门

    题目中的几个操作,直接splay搞一下即可:

    1. 把s旋转到根,左子树接到右子树
    2. 把s旋转到根,右子树接到左子树
    3. 交换s相邻的信息即可
    4. 把s旋转到根,左子树的大小即为答案
    5. 找第k大

    没了

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #define N 100000
    
    using namespace std;
    
    int n, m, cnt, rt;
    int son[N][2], size[N], f[N], pos[N], w[N];
    
    inline int read()
    {
    	int x = 0, f = 1;
    	char ch = getchar();
    	for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
    	for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
    	return x * f;
    }
    
    inline int get(int x)
    {
    	return son[f[x]][1] == x;
    }
    
    inline void update(int x)
    {
    	size[x] = size[son[x][0]] + size[son[x][1]] + 1;
    }
    
    inline void rotate(int x)
    {
    	int fa = f[x], ffa = f[fa], p = get(x);
    	son[fa][p] = son[x][p ^ 1], f[son[x][p ^ 1]] = fa;
    	son[x][p ^ 1] = fa, f[fa] = x;
    	if(ffa) son[ffa][son[ffa][1] == fa] = x; f[x] = ffa;
    	update(fa), update(x);
    }
    
    inline void splay(int x, int y)
    {
    	for(int fa; (fa = f[x]) != y; rotate(x))
    		if(f[fa] != y) rotate(get(fa) == get(x) ? fa : x);
    	if(!y) rt = x;
    }
    
    inline void top_bottom(int x, int p)
    {
    	splay(pos[x], 0);
    	if(!son[rt][p]) return;
    	if(!son[rt][p ^ 1]) son[rt][p ^ 1] = son[rt][p], son[rt][p] = 0;
    	else
    	{
    		x = son[rt][p ^ 1];
    		while(son[x][p]) x = son[x][p];
    		son[x][p] = son[rt][p], f[son[rt][p]] = x;
    		son[rt][p] = 0, splay(son[x][p], 0);
    	}
    }
    
    inline int build(int l, int r, int fa)
    {
    	if(l > r) return 0;
    	int mid = (l + r) >> 1, now = ++cnt;
    	son[now][0] = build(l, mid - 1, now);
    	w[now] = read(), size[now] = 1, f[now] = fa, pos[w[now]] = now;
    	son[now][1] = build(mid + 1, r, now);
    	update(now);
    	return now;
    }
    
    inline void ist(int p, int x)
    {
    	if(!p) return;
    	splay(pos[x], 0);
    	if(p == -1) p = 0;
    	x = son[rt][p];
    	while(son[x][p ^ 1]) x = son[x][p ^ 1];
    	if(x) swap(pos[w[rt]], pos[w[x]]), swap(w[rt], w[x]);
    }
    
    inline void ask(int x)
    {
    	splay(pos[x], 0);
    	printf("%d
    ", size[son[rt][0]]);
    }
    
    inline int query(int k)
    {
    	int x = rt;
    	while(x)
    	{
    		if(size[son[x][0]] + 1 == k) return w[x];
    		else if(size[son[x][0]] >= k) x = son[x][0];
    		else k -= size[son[x][0]] + 1, x = son[x][1];
    	}
    }
    
    int main()
    {
    	int i, x;
    	char s[10];
    	n = read();
    	m = read();
    	rt = build(1, n, 0);
    	for(i = 1; i <= m; i++)
    	{
    		scanf("%s", s);
    		switch(s[0])
    		{
    			case 'T': top_bottom(read(), 0); break;
    			case 'B': top_bottom(read(), 1); break;
    			case 'I': ist(read(), read()); break;
    			case 'A': ask(read()); break;
    			case 'Q': printf("%d
    ", query(read())); break;
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    SQL PASS 北京2013年6月15日活动照片集
    XML约束文档DTD
    内存管理之虚拟页式分配
    设备驱动中异步通知编程
    王家林 云计算分布式大数据Hadoop实战高手之路第七讲Hadoop图文训练课程:通过HDFS的心跳来测试replication具体的工作机制和流程
    安装配置netanalyzer/netsnmp3.5.7_rc1
    理解Java对象序列化——Serializable接口
    世界500强高频逻辑推理智力面试题(二)
    2column left navigation 中遇到的问题
    Visual Studio 2010 无法打开 源 文件 "iostream.h"
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/8304877.html
Copyright © 2011-2022 走看看