Time Limit: 2000MS | Memory Limit: 30000K | |
Total Submissions: 15619 | Accepted: 5292 | |
Case Time Limit: 1000MS |
Description
moves and counts.
* In a move operation, Farmer John asks Bessie to move the stack containing cube X on top of the stack containing cube Y.
* In a count operation, Farmer John asks Bessie to count the number of cubes on the stack with cube X that are under the cube X and report that value.
Write a program that can verify the results of the game.
Input
* Lines 2..P+1: Each of these lines describes a legal operation. Line 2 describes the first operation, etc. Each line begins with a 'M' for a move operation or a 'C' for a count operation. For move operations, the line also contains two integers: X and Y.For count operations, the line also contains a single integer: X.
Note that the value for N does not appear in the input file. No move operation will request a move a stack onto itself.
Output
Sample Input
6
M 1 6
C 1
M 2 4
M 2 6
C 3
C 4
Sample Output
1
0
2
题目大意:初始时有n个栈,每个栈中只有一个元素,按顺序标为1-n.给出两种操作M,C.M x y:把含有x的栈移至含y的栈后面.C x:查询x所在栈中在x前面的元素个数.
此题可以用并查集,用tree[]数组表示各个数的父亲节点,属于同一集合的在同一栈中,对根节点x,tree[x]<0;-tree[x]表示整个集合的元素个数。而num[]数组表示在同一集合中,子节点到父亲节点的物理元素个数。通过find,路径压缩操作就可得到当前元素到根节点的数目。
代码:
#include<iostream> #include<cstdio> #define N 30005 using namespace std; int p; int tree[N],num[N]; void init() { for(int i=0;i<N;i++) { tree[i]=-1; num[i]=0; } } int find(int x) { if(tree[x]<=0) return x; int t=tree[x]; tree[x]=find(tree[x]); num[x]=num[x]+num[t]; return tree[x]; } void union_set(int a,int b) { int x,y; x=find(a); y=find(b); if(x==y) return ; int temp=tree[x]; tree[x]=y; num[x]=-tree[y]; tree[y]=tree[y]+temp;
} int main() { // freopen("in.txt","r",stdin); char c; int a,b; scanf("%d",&p); getchar(); init(); while(p--) { scanf("%c",&c); if(c=='M') { scanf("%d%d",&a,&b); getchar(); union_set(a,b); } else if(c=='C') { scanf("%d",&a); getchar();
if(find(a)==a) printf("0\n"); else printf("%d\n",num[a]);
} } return 0; }