题目:

蒜头君在玩一种接龙的游戏,蒜头君有 30000 张卡片分别放在 30000 列,每列依次编号为 1,2,…,300001,2,…,30000。同时,蒜头君也把每张卡片依次编号为 1,2,…,30000 

游戏开始,蒜头君让让第 ii 张卡片处于第i(i=1,2,…,30000) 列。然后蒜头君会发出多次指令,每次调动指令 M i j 会将第 i 张卡片所在的队列的所有卡片,作为一个整体(头在前尾在后)接至第 j 张卡片所在的队列的尾部。

蒜头君还会查看当前的情况,发出 CC ii jj 的指令,即询问电脑,第 ii 张卡片与第 jj 张卡片当前是否在同一个队列中,如果在同一列中,那么它们之间一共有多少张卡片。

聪明的你能不能编写程序处理蒜头君的指令,以及回答蒜头君的询问呢? 
输入格式 :
第一行有一个整数 TT(5000001≤T≤500000),表示总共有 T 条指令。 
以下有 T行,每行有一条指令。指令有两种格式: 
M i j:i 和 j 是两个整数(300001≤i,j≤30000),表示指令涉及的卡片编号。你需要让第 i 张卡片所在的队列的所有卡片,作为一个整体(头在前尾在后)接至第 jj 张卡片所在的队列的尾部,输入保证第 i 号卡片与第 j 号卡片不在同一列。 
C i j:i 和 j 是两个整数(1≤i,j≤30000),表示指令涉及的卡片编号。该指令是蒜头君的询问指令。 
输出格式 :
如果是蒜头君调动指令,则表示卡片排列发生了变化,你的程序要注意到这一点,但是不要输出任何信息; 
如果是蒜头君的询问指令,你的程序要输出一行,仅包含一个整数,表示在同一列上,第 ii 号卡片与第 jj 号卡片之间的卡片数目(不包括第i张卡片和第 j 张卡片)。如果第i 号卡片与第 j 号卡片当前不在同一个队列种中,则输出 -1。 
样例输入 

M 2 3 
C 1 2 
M 2 4 
C 4 2 
样例输出 
-1 
1

  1 #include <map>
  2 #include <set>
  3 #include <stack>
  4 #include <queue>
  5 #include <cmath>
  6 #include <string>
  7 #include <limits>
  8 #include <cstdio>
  9 #include <vector>
 10 #include <cstdlib>
 11 #include <cstring>
 12 #include <iostream>
 13 #include <algorithm>
 14 #define Scc(c) scanf("%c",&c)
 15 #define Scs(s) scanf("%s",s)
 16 #define Sci(x) scanf("%d",&x)
 17 #define Sci2(x, y) scanf("%d%d",&x,&y)
 18 #define Sci3(x, y, z) scanf("%d%d%d",&x,&y,&z)
 19 #define Scl(x) scanf("%I64d",&x)
 20 #define Scl2(x, y) scanf("%I64d%I64d",&x,&y)
 21 #define Scl3(x, y, z) scanf("%I64d%I64d%I64d",&x,&y,&z)
 22 #define Pri(x) printf("%d\n",x)
 23 #define Prl(x) printf("%I64d\n",x)
 24 #define Prc(c) printf("%c\n",c)
 25 #define Prs(s) printf("%s\n",s)
 26 #define For(i,x,y) for(int i=x;i<y;i++)
 27 #define For_(i,x,y) for(int i=x;i<=y;i++)
 28 #define FFor(i,x,y) for(int i=x;i>y;i--)
 29 #define FFor_(i,x,y) for(int i=x;i>=y;i--)
 30 #define Mem(f, x) memset(f,x,sizeof(f))
 31 #define LL long long
 32 #define ULL unsigned long long
 33 #define MAXSIZE 500005
 34 #define INF 0x3f3f3f3f
 35
 36 const int mod=1e9+7;
 37 const double PI = acos(-1.0);
 38
 39 using namespace std;
 40
 41 int pre[MAXSIZE];
 42 int num[MAXSIZE];
 43 int size[MAXSIZE];
 44 void init(int n)
 45 {
 46     For_(i,1,n)
 47     {
 48         pre[i]=i;
 49         num[i]=0;
 50         size[i]=1;
 51         //   f[i]=-1;
 52     }
 53 }
 54 int find(int x)
 55 {
 56     if(x==pre[x])
 57         return x;
 58     int y=pre[x];
 59     pre[x]=find(pre[x]);
 60     num[x]+=num[y];
 61     return pre[x];
 62 }
 63 void merge(int x,int y)
 64 {
 65     int xx=find(x);
 66     int yy=find(y);
 67     if(xx!=yy)
 68     {
 69         pre[xx]=yy;
 70         num[xx]=size[yy];
 71         size[yy]+=size[xx];
 72     }
 73 }
 74 int main()
 75 {
 76     int t;
 77     Sci(t);
 78     getchar();
 79     init(t);
 80     while(t--)
 81     {
 82         char c;
 83         int x,y;
 84         // Scc(c);
 85         //Sci2(x,y);
 86         scanf("%c %d %d",&c,&x,&y);
 87         getchar();
 88         if(c=='M')
 89             //pre[x]=pre[y];
 90             merge(x,y);
 91         else
 92         {
 93             if(find(x)!=find(y))
 94                 Pri(-1);
 95             else
 96                 Pri(abs(num[x]-num[y])-1);
 97         }
 98     }
 99     return 0;
100 }
View Code

详解:https://blog.csdn.net/Liukairui/article/details/79354053

02-12 21:06