• splay


    #include<cstdio>
    #include<algorithm>
    #define inf 0x7fffffff
    #define N 100010
    
    using namespace std;
    
    inline int read()
    {
        int x = 0,f = 1;char ch = getchar();
        while (ch < '0' || ch > '9') {if (ch == '-')f = -1;ch = getchar();}
        while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
        return x * f;
    }
    
    struct Data{
    	int data,pos;
    }a[N];
    
    bool cmp1 (Data a,Data b)
    {
    	if (a.data == b.data) return a.pos < b.pos;
    	return a.data < b.data;
    }
    
    int rev[N], mn[N], ch[N][2], mnpos[N], data[N], fa[N], size[N], n, root;
    
    inline void pushdown (int x)
    {
    	if (rev[x])
    	{
    		rev[x] = 0;
    		rev[ch[x][0]] ^= 1;
    		swap(ch[ch[x][0]][0], ch[ch[x][0]][1]);
    		rev[ch[x][1]] ^= 1;
    		swap(ch[ch[x][1]][0], ch[ch[x][1]][1]);
    	}
    }
    
    inline void pushup (int x)
    {
    	mn[x] = min(data[x], min(mn[ch[x][0]], mn[ch[x][1]]));
    	if(mn[x] == data[x]) mnpos[x] = x;
    	else if (mn[x] == mn[ch[x][0]]) mnpos[x] = mnpos[ch[x][0]];
    	else mnpos[x] = mnpos[ch[x][1]];
    	size[x] = size[ch[x][0]] + size[ch[x][1]] + 1;
    }
    
    inline int son (int x)
    {
    	return ch[fa[x]][1] == x;
    }
    
    inline void rotate (int x)
    {
    	int y = fa[x], z = fa[y], b = son(x), c = son(y), a = ch[x][!b];
    	if (z) ch[z][c] = x; else root = x; fa[x] = z;
    	if (a) fa[a] = y; ch[y][b] = a;
    	ch[x][!b] = y; fa[y] = x;
    	pushup(y); pushup(x);
    }
    
    void splay (int &x,int i)
    {
    	while(fa[x] != i)
    	{
    		int y = fa[x], z = fa[y];
    		if(z == i)
    			rotate (x);
    		else
    		{
    			pushdown (z); pushdown (y); pushdown (x);
    			if(son (x) == son (y))
    				rotate (y); rotate (x);
    			else
    				rotate (x); rotate (x);
    		}
    	}
    }
    
    inline int getkth (int k,int rt)
    {
    	pushdown (rt);
    	if(k == size[ch[rt][0]] + 1) return rt;
    	if(k < size[ch[rt][0]] + 1) return getkth (k, ch[rt][0]);
    	return getkth (k - 1 - size[ch[rt][0]], ch[rt][1]);
    }
    
    inline void reverse (int l, int r)
    {
    	int ll = getkth (l - 1, root),rr = getkth (r + 1, root), p;
    	splay(ll, 0); splay(rr, ll);
    	p = ch[rr][0]; rev[p] ^= 1;
    	swap(ch[p][0], ch[p][1]);
    }
    
    inline int getmnpos (int l, int r)
    {
    	int ll = getkth (l - 1, root);
    	int rr = getkth (r + 1, root);
    	splay(ll, 0);
    	splay(rr, ll);
    	return mnpos[ch[rr][0]];
    }
    
    void dfs (int x)
    {
    	if( !x ) return;
    	pushdown (x);
    	dfs (ch[x][0]);
    	printf("%d ",x);
    	dfs (ch[x][1]);
    }
    
    int main()
    {
    	n = read();
    	for(int i = 2; i <= n + 1; i ++)
    	{
    		data[i] = read();
    		a[i].data = data[i];
    		a[i].pos = i;
    	}
    	sort(a + 2, a + n + 2, cmp1);
    	for(int i = 2; i <= n + 1; i ++)
    		data[a[i].pos] = i;
    	for(int i = 0; i <= n + 2; i ++) mn[i] = inf;
    	data[0] = inf; data[1] = inf; data[n + 2] = inf; root = 1; size[0] = 0;
    	for(int i = 1; i <= n + 2; i ++)
    	{
    		fa[i] = i - 1;
    		ch[i][1] = i + 1;
    	}
    	ch[n + 2][1] = 0;
    	for(int i = n + 2; i >= 1; i --)
    		pushup (i);
    	for(int i = 1; i <= n; i ++)
    	{
    		int p = getmnpos (i + 1, n + 1);
    		splay (p, 0);
    		printf("%d",size[ch[p][0]]);
    		reverse(i + 1, size[ch[p][0]] + 1);
    		if(i != n) printf(" ");
    	}
    	printf("
    ");
    	return 0;
    }
    

      

  • 相关阅读:
    银行卡号每隔四位添加一个分隔符
    clipboard.js实现文本复制
    选中|复制文本
    react---之下拉菜单默认选中的值始终不变的问题
    create-react-app支持less配置
    数对
    安置路灯
    被三整除
    牛牛找工作
    C++ std::pair
  • 原文地址:https://www.cnblogs.com/lyqlyq/p/7256103.html
Copyright © 2020-2023  润新知