hdu2475 Box
2015-12-06 10:31
417 查看
Box
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2690 Accepted Submission(s): 788
Problem Description
There are N boxes on the ground, which are labeled by numbers from 1 to N. The boxes are magical, the size of each one can be enlarged or reduced arbitrarily.
Jack can perform the “MOVE x y” operation to the boxes: take out box x; if y = 0, put it on the ground; Otherwise, put it inside box y. All the boxes inside box x remain the same. It is possible that an operation is illegal, that is, if box y is contained (directly
or indirectly) by box x, or if y is equal to x.
In the following picture, box 2 and 4 are directly inside box 6, box 3 is directly inside box 4, box 5 is directly inside box 1, box 1 and 6 are on the ground.
The picture below shows the state after Jack performs “MOVE 4 1”:
Then he performs “MOVE 3 0”, the state becomes:
During a sequence of MOVE operations, Jack wants to know the root box of a specified box. The root box of box x is defined as the most outside box which contains box x. In the last picture, the root box of box 5 is box 1, and box 3’s root box is itself.
Input
Input contains several test cases.
For each test case, the first line has an integer N (1 <= N <= 50000), representing the number of boxes.
Next line has N integers: a1, a2, a3, ... , aN (0 <= ai <= N), describing the initial state of the boxes. If ai is 0, box i is on the ground, it is not contained by any box; Otherwise, box i is directly inside box ai. It is guaranteed that the input state is
always correct (No loop exists).
Next line has an integer M (1 <= M <= 100000), representing the number of MOVE operations and queries.
On the next M lines, each line contains a MOVE operation or a query:
1. MOVE x y, 1 <= x <= N, 0 <= y <= N, which is described above. If an operation is illegal, just ignore it.
2. QUERY x, 1 <= x <= N, output the root box of box x.
Output
For each query, output the result on a single line. Use a blank line to separate each test case.
Sample Input
2
0 1
5
QUERY 1
QUERY 2
MOVE 2 0
MOVE 1 2
QUERY 1
6
0 6 4 6 1 0
4
MOVE 4 1
QUERY 3
MOVE 1 4
QUERY 1
Sample Output
1
1
2
1
1
Source
2008 Asia Regional Chengdu
Recommend
lcy
DFS序+splay,重点在于DFS序将一棵子树转化为一个区间
咦?这道题splay好像很好写…2333
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstdlib> #include<cstring> #define F(i,j,n) for(int i=j;i<=n;i++) #define D(i,j,n) for(int i=j;i>=n;i--) #define LL long long #define pa pair<int,int> #define MAXN 100010 #define INF 1000000000 using namespace std; int flag=0,rt,tot,cnt,n,m; int c[MAXN][2],fa[MAXN],a[MAXN],head[MAXN]; bool f[MAXN]; char s[10]; struct edge_type { int next,to; }e[MAXN]; 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; } inline void add_edge(int u,int v) { e[++tot]=(edge_type){head[u],v}; head[u]=tot; } inline void build(int &k,int l,int r,int father) { if (l>r) return; int mid=(l+r)>>1; k=a[mid];c[k][0]=c[k][1]=0;fa[k]=father; build(c[k][0],l,mid-1,k);build(c[k][1],mid+1,r,k); } inline void rotate(int x,int k) { int y=fa[x],z=fa[y],l=(c[y][1]==x),r=l^1; c[z][c[z][1]==y]=x; fa[x]=z;fa[y]=x;fa[c[x][r]]=y; c[y][l]=c[x][r];c[x][r]=y; } inline void splay(int x,int k) { if (x!=k) while (fa[x]!=k) rotate(x,k); } inline void move(int x,int y) { if (x==y) return; splay(x,0);splay(x+n,x); for(int i=y;i;i=fa[i]) if (c[x+n][0]==i) return; int a=c[x][0],b=c[x+n][1]; c[x][0]=c[x+n][1]=fa[a]=fa[b]=0; if (a&&b) { while (c[b][0]) b=c[b][0]; c[b][0]=a;fa[a]=b; } if (!y) return; splay(y,0); int tmp; for(tmp=c[y][1];c[tmp][0];tmp=c[tmp][0]); splay(tmp,y); c[tmp][0]=x;fa[x]=tmp; } inline int query(int x) { splay(x,0); for(;c[x][0];x=c[x][0]); return x; } inline void dfs(int x) { a[++cnt]=x; for(int i=head[x];i;i=e[i].next) dfs(e[i].to); a[++cnt]=x+n; } int main() { int x,y; while (~scanf("%d",&n)) { if (flag++) printf("\n"); rt=tot=0; memset(head,0,sizeof(head)); memset(fa,0,sizeof(fa)); memset(c,0,sizeof(c)); memset(f,false,sizeof(f)); F(i,1,n) { x=read(); if (x) add_edge(x,i); else f[i]=true; } F(i,1,n) if (f[i]) { cnt=0; dfs(i); build(rt,1,cnt,0); } m=read(); F(i,1,m) { scanf("%s",s); if (s[0]=='Q') { x=read(); printf("%d\n",query(x)); } else { x=read();y=read(); move(x,y); } } } }
相关文章推荐
- Bad Hair Day
- Code Forces 601 A. The Two Routes(Floyd)
- html5 postMessage解决跨域、跨窗口消息传递
- crash发生时,新开一个进程的activity用于显示crash发生的详情
- 操作系统进程环境
- javaScript基础入门
- 1026. Table Tennis (30)
- Zookeeper工作原理二
- 桂林龙胜游
- c++操作符优先级表格 + 记忆方法整理
- log4j配置说明
- 河床
- UVA230-图书馆管理
- HTML5的 input:file上传类型控制
- 1025. PAT Ranking (25)
- AngularJS进阶(十八)在AngularJS应用中集成科大讯飞语音输入功能
- AngularJS进阶(十八)在AngularJS应用中集成科大讯飞语音输入功能
- 1024. Palindromic Number (25)
- Zookeeper工作原理一
- 【UML】之用例图