题意:假设当前有 \(n\) 个点,求最多的边数,使得桥的数量 \(\ge\lceil\dfrac{m}{2}\rceil\)。
我们考虑构造,首先,整张图一共只有一个双连通分量。因为我们如果有两个双连通分量,完全可以通过同构结合成一个。而从双连通分量之外的所有边都是桥,不妨假设它就是一条链。那么,链上有 \(n-x\) 条边,右边的 \(x\) 个点之间的所有边不是桥,最多有 \(x(x-1)/2\) 条。又因为桥的数量必须在两倍以上,最多有 \(n-x\) 条边。
所以选 \(x\) 个点的最优边数就是 \(n-i+\min(n-i,i(i-1)/2)\),也就是 \(\min(2n-2i,n-i+i(i-1)/2)\)。
我们发现这两个部分左边单调减,右边单调增(\(i^2\) 增长率在 \(i\ge 1\) 的情况下大于 \(n-i\)),那么最大值一定出现在两边相等的时候。
解方程 \(n-i=i(i-1)/2\)
\[2n=i(i+1) \]\[i^2+i-2n=0 \]\[\Delta=1^2-4(-2n)=1+8n \]\[x_1=\dfrac{-1+\sqrt{\Delta}}{2},x_2=\dfrac{-1-\sqrt{\Delta}}{2} \]\[\because x>0 \]\[\therefore x=\dfrac{-1+\sqrt{1+8n}}{2} \]所以我们找到了最大值出现的位置。但是因为整数计算过程中的误差,真正的解也可能是 \(x+1\),都计算出来找最小值即可。
复杂度取决于 'sqrt' 的实现,如果是二分法则为 \(O(\log n)\),如果是牛顿迭代(不知道是什么,但是网上说有),复杂度就是 \(O(1)\) 的
int n;
inline void solve(){
cin>>n;
ll ans=0,d=1+8*(ll)n;
d=(-1+sqrt(d))/2;
for(int i=max(1ll,d);i<=min((ll)n,d+1);i++){
ans=max(ans,n-i+min((ll)n-i,1ll*i*(i-1)/2));
}cout<<ans<<'\n';
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin>>t;
rd(_,t)solve();
return 0;
}
//Crayan_r
标签:连通,个点,Level,Generation,dfrac,sqrt,CF818F,Delta,2n
From: https://www.cnblogs.com/jucason-xu/p/17149404.html