zoukankan      html  css  js  c++  java
  • Hdu 3487 play the chain

    Description
    瑶瑶很喜欢玩项链,她有一根项链上面有很多宝石,宝石从1到n编号。
    首先,项链上的宝石的编号组成一个序列:1,2,3,...,n。
    她喜欢两种操作:
    1.CUT a b c:他会先将a至b号宝石切下来,然后接到c号宝石后面,组成一个新的项链。
    举个例子,如果n=8,那么这个项链上的宝石编号依次为:1 2 3 4 5 6 7 8;'CUT 3 5 4',首先我们把3到5号宝石切下,项链变成了:1 2 6 7 8;然后接到4号宝石后面,此时的4号宝石为7,所以此时的项链变成了:1 2 6 7 3 4 5 8.
    2.FLIP a b:像第一个操作一样我们先将a至b号宝石切下来,然后将其旋转180°,变成与原来相反的链,在插入到项链的相 同位置中。
    举个例子,取操作1中的链:1 2 3 4 5 6 7 8,执行FLIP 2 6操作,则项链将变成:1 6 5 4 3 2 7 8.
    他想知道经过m个操作之后项链会变成怎样。

    Input
    对于每一个数据,第一行会有两个整数:n m(1<=n,m<=300000) n代表宝石的个数,m代表操作的个数。
    接下来有M行 有两个操作:
    CUT A B C //代表CUT操作,1<=A<=B<=N, 0<=C<=N-(B-A+1).
    FLIP A B //代表FLIP操作,1<=A<=B<=N.
    输出的结尾将会有两个负数,他们不能当做操作.

    Output
    对于每一个数据,你需要输出N个整数,任两个数字间用一个空格分开,代表最终得到的项链的从1到N的宝石的序列号。

    Sample Input
    8 2
    CUT 3 5 4
    FLIP 2 6
    -1 -1

    Sample Output
    1 4 3 7 6 2 5 8


    splay区间操作请见浅谈算法——splay

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define inf 0x7f7f7f7f
    using namespace std;
    typedef long long ll;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')    f=-1;
    	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    inline void print(int x){
    	if (x>=10)     print(x/10);
    	putchar(x%10+'0');
    }
    const int N=3e5;
    int n,m;
    struct Splay{
    	#define T(x) (tree[f[x]][1]==x)
    	int tree[N+10][2],f[N+10],size[N+10];
    	bool flag[N+10];
    	int root,cnt;
    	void clear(){
    		root=cnt=0;
    		memset(f,0,sizeof(f));
    		memset(tree,0,sizeof(tree));
    		memset(size,0,sizeof(size));
    		memset(flag,0,sizeof(flag));
    	}
    	void pushdown(int x){
    		if (!flag[x])	return;
    		swap(tree[x][0],tree[x][1]);
    		flag[tree[x][0]]^=1;
    		flag[tree[x][1]]^=1;
    		flag[x]=0;
    	}
    	void write(int x){
    		if (!x)	return;
    		pushdown(x);
    		write(tree[x][0]);
    		if (x<=n)	++cnt!=n?printf("%d ",x):printf("%d
    ",x);
    		write(tree[x][1]);
    	}
    	void build(){
    		root=n+1;
    		for (int i=1;i<=n;i++)	f[i]=i+1,size[i]=i+1,tree[i+1][0]=i;
    		f[n+2]=1,size[n+2]=1,tree[1][0]=n+2;
    		size[root]=n+2;
    	}
    	void updata(int x){size[x]=size[tree[x][0]]+size[tree[x][1]]+1;}
    	void move(int x){
    		int fa=f[x],son=tree[x][T(x)^1];
    		tree[x][T(x)^1]=fa;
    		tree[fa][T(x)]=son;
    		if (son)	f[son]=fa;
    		f[x]=f[fa];
    		if (f[x])	tree[f[x]][T(fa)]=x;
    		f[fa]=x;
    		updata(fa),updata(x);
    	}
    	void splay(int x){
    		while (f[x]){
    			if (f[f[x]])	T(x)==T(f[x])?move(f[x]):move(x);
    			move(x);
    		}
    		root=x;
    	}
    	int find(int x,int i){
    		if (!i)	return 0;
    		pushdown(i);
    		if (size[tree[i][0]]+1==x)	return i;
    		if (x<=size[tree[i][0]])	return find(x,tree[i][0]);
    		return find(x-size[tree[i][0]]-1,tree[i][1]);
    	}
    	void flip(){//区间翻转,打个标记即可
    		int x=read(),y=read();
    		x=find(x,root),splay(x);
    		y=find(y+2,root),splay(y);
    		if (f[x]!=root)	move(x);
    		flag[tree[x][1]]^=1;
    	}
    	void consert(int x,int fa){//连边
    		if (tree[f[x]][T(x)]==x)	tree[f[x]][T(x)]=0;
    		f[tree[fa][0]=x]=fa;
    	}
    	void up(int x){while (f[x])	updata(x),x=f[x];}//向上更新
    	void cut(){//区间切断
    		int x=read(),y=read(),z=read();
    		x=find(x+1,root),splay(x);
    		y=find(y+2,root),splay(y);
    		if (f[x]!=root)	move(x);
    		consert(tree[x][0],f[x]);
    		z=find(z+2,root);
    		consert(tree[z][0],x);
    		consert(x,z);
    		up(x);
    	}
    }T;
    char s[10];
    int main(){
    	while (1){
    		T.clear();
    		n=read(),m=read();
    		if (n==-1&&m==-1)	break;
    		T.build();
    		for (int i=1;i<=m;i++){
    			scanf("%s",s);
    			if (s[0]=='F')	T.flip();
    			if (s[0]=='C')	T.cut();
    		}
    		T.write(T.root);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Anagram
    HDU 1205 吃糖果(鸽巢原理)
    Codeforces 1243D 0-1 MST(补图的连通图数量)
    Codeforces 1243C Tile Painting(素数)
    Codeforces 1243B2 Character Swap (Hard Version)
    Codeforces 1243B1 Character Swap (Easy Version)
    Codeforces 1243A Maximum Square
    Codeforces 1272E Nearest Opposite Parity(BFS)
    Codeforces 1272D Remove One Element
    Codeforces 1272C Yet Another Broken Keyboard
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/9479739.html
Copyright © 2011-2022 走看看