题目描述:
给定一个长度为 nn 的数组 a[]a[],有三种操作:
- 操作1:格式 11 xx yy 将数组中值为 xx 的数据改为 a[y]a[y]
- 操作2:格式 22 xx 输出 a[x]a[x] 的值为多少
- 操作3:格式 33 xx 输出值为 xx 的数有多少个
输入数据:
第一行有一个正整数 nn,表示数组长度。
第二行有 nn 个正整数,第 ii 个正整数为 a[i]a[i]。
第三行有一个正整数 qq,表示操作次数,之后的 qq 行每行一种操作,
第一种操作的格式为 : 11 xx yy
第二种操作的格式为 : 22 xx
第三种操作的格式为 : 33 xx
输出数据:
对于每次第二种和第三种操作,输出对应的值,每次输出占一行。
评测用例规模与约定:
对于 40% 的数据:1 le n,q le 1000 ,1 le a[i] le 1000001≤n,q≤1000,1≤a[i]≤100000.
对于 100% 的数据: 1 le n,q le 100000,1 le a[i] le 1000001≤n,q≤100000,1≤a[i]≤100000.
样例输入
3 1 2 3 3 1 2 3 2 3 3 3
样例输出
3 2
样例解释
最初数组为 [1,2,3][1,2,3]。
第一次操作将值为 22 的数据变为 a[3]a[3]。
数组变成 [1,3,3][1,3,3]。
第二次操作询问 a[2]a[2] 的值为多少。输出答案为: 33。
第三次操作询问值为 33 的元素有多少个。输出答案为: 22。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=2e5+10; const ll mod=1e9+7; const double eps=1e-7; int T,n,q,op,x,y; int c[maxn],to[maxn],cnt[maxn]; int getf(int cur){ return cur==to[cur]?cur:to[cur]=getf(to[cur]); } int solve(int cur){ return getf(c[cur]); } int main() { //freopen("1.txt","r",stdin); scanf("%d",&n); for(int i=0;i<=100006;++i)to[i]=i; for(register int i=1;i<=n;++i)scanf("%d",c+i),cnt[c[i]]++; scanf("%d",&q); for(register int i=1;i<=q;++i){ scanf("%d",&op); if(op==1){ scanf("%d%d",&x,&y); int nx=solve(y); if(!cnt[x]||x==nx)continue; to[x]=nx; cnt[nx]+=cnt[x],cnt[x]=0; } else if(op==2){ scanf("%d",&x); printf("%d ",solve(x)); } else{ scanf("%d",&x); printf("%d ",cnt[x]); } } return 0; }