#pragma GCC optimize(2)
#pragma GCC optimize("Ofast")
#include<map>
#include<set>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<string>
#include<bitset>
#include<numeric>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN=1e5+10;
const int N=1e5;
const int INF=0x3f3f3f3f;
const long long LINF=0x3f3f3f3f3f3f3f3f;
#include<random>
#include<chrono>
mt19937 rnd((unsigned int)chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()).count());
int n,m;
int fat[MAXN];
basic_string <int> tr[MAXN];
void dfs(int x){
for(int to:tr[x])
{
if(to^fat[x]){
fat[to]=x;
dfs(to);
}
}
}
inline int find(int x){
while(fat[x])
{
x=fat[x];
}
return x;
}
#define pii pair<int,int>
basic_string <pii> e;
inline void add_edge(int x,int y){
tr[x].insert(lower_bound(tr[x].begin(),tr[x].end(),y),y);
e.insert(lower_bound(e.begin(),e.end(),pii(x,y)),pii(x,y));
}
inline void del_edge(int x,int y){
tr[x].erase(lower_bound(tr[x].begin(),tr[x].end(),y));
e.erase(lower_bound(e.begin(),e.end(),pii(x,y)));
}
inline void make(){
n=100000;
m=500000;
printf("%d %d\n",n,m);
while(m--)
{
int opt=(rnd()&1)+1,k=rnd()%n+1;
int x,y;
if(e.empty()){
opt=1;
}
if((int)e.size()==(n-1)<<1){
opt=2;
}
if(opt==1){
remake:
x=rnd()%n+1;
y=rnd()%n+1;
if(find(x)==find(y)){
goto remake;
}
fat[y]=0;
dfs(y);
fat[y]=x;
add_edge(x,y);
add_edge(y,x);
}
else{
tie(x,y)=e[rnd()%(int)e.size()];
if(fat[y]^x){
swap(x,y);
}
fat[y]=0;
del_edge(x,y);
del_edge(y,x);
}
printf("%d %d %d %d\n",opt,x,y,k);
}
}
signed main(){
freopen("data.in","w",stdout);
make();
return 0;
}
可以看得出来数据造出来很水(造数据复杂度理论都是 O(n2) 的),但你可以 n 开小一点 m 开大一点。