#include<bits/stdc++.h> using namespace std; const int maxn=1e6+14; int father[maxn]; int cnt[maxn]; int num[maxn]; int isRoot[maxn]; int N,Q; int block; bool cmp (int a,int b) { return a>b; } void init () { for (int i=1;i<=N;i++) { cnt[i]=0; num[i]=1; father[i]=i; isRoot[i]=1; } block=N; } int findfather (int x) { int a=x; while (x!=father[x]) x=father[x]; while (a!=father[a]) { int z=a; a=father[a]; father[z]=x; } return x; } void Union (int a,int b) { int faA=findfather(a); int faB=findfather(b); if (faA==faB) { cnt[faA]++; return; } if (faA<faB) swap(faA,faB); father[faA]=faB; block--; num[faB]+=num[faA]; cnt[faB]=cnt[faB]+cnt[faA]+1; isRoot[faA]=0; } int getMin (int k) { return max(1,block-k); } int getMax (int k) { int ans=0; for (int i=1;i<=N;i++) ans+=isRoot[i]*(num[i]*(num[i]-1)/2-cnt[i]); if (k<=ans) return block; vector<int> vi; for (int i=1;i<=N;i++) if (isRoot[i]) vi.push_back(num[i]); sort(vi.begin(),vi.end(),cmp); k-=ans; int ck; for (ck=0;ck<block-1;ck++) { k-=(vi[ck]*vi[ck+1]); vi[ck+1]+=vi[ck]; if (k<=0) break; } return block-ck-1; } int main () { int T; scanf("%d",&T); while (T--) { scanf("%d%d",&N,&Q); init(); int a,b; int query; while (Q--) { scanf("%d",&query); if (query==1) { scanf("%d%d",&a,&b); Union(a,b); } else { scanf("%d",&a); printf("%d %d\n",getMin(a),getMax(a)); } } } return 0; }
来源:https://www.cnblogs.com/zhanglichen/p/12442977.html