正解:构造+图论
解题报告:
先简要表达下题意
一个图上,如果存在(a,b)满足a<b且存在从a到b再回到a的路径,每条道路被经过至多一次,我们称(a,b)为完美点对
试构造一个点数和边数不超过5000的无向连通图,其完美点对数量恰好为K
k<=107
昂这题也比较简单啊,,,就每次都尽量大地构边双联通分量
然后把他们连起来就好辣
显然连起来是不会构造完美点对的
然后关于边双联通分量,可以得到当有n个点的时候完美点对的数量为n(n-1)/2
然后就好辣?
over!
![](https://i-blog.csdnimg.cn/blog_migrate/a2b7024cb6a8cccd23244148c90016f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/aa7790439652fcf252898472b6dc57b7.gif)
#include<bits/stdc++.h> using namespace std; #define ll int #define il inline #define rg register #define mp make_pair #define rp(i,x,y) for(rg ll i=x;i<=y;++i) ll n,cntv,cnte; vector< pair<ll,ll> >as; il ll read() { rg char ch=getchar();rg ll x=0;rg bool y=1; while(ch!='-' && (ch>'9' || ch<'0'))ch=getchar(); if(ch=='-')ch=getchar(),y=0; while(ch<='9' && ch>='0')x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar(); return y?x:-x; } il ll gt(ll x){ll tmp=sqrt(x)+5;while(tmp*(tmp-1)>(x<<1))--tmp;return tmp;} int main() { n=read(); while(n) { ll tmp=(1+sqrt(8*N+1))/2+ 1e-8;if(cntv)as.push_back(mp(1,cntv+1)),++cnte; rp(i,cntv+1,cntv+tmp-1)as.push_back(mp(i,i+1)),++cnte;as.push_back(mp(cntv+tmp,cntv+1)),++cnte; cntv+=tmp;n-=tmp*(tmp-1)/2; } printf("%d %d\n",cntv,cnte); rp(i,0,cnte-1)printf("%d %d\n",as[i].first,as[i].second); return 0; }