QOJ10892
题意
给定 \(n,m\),求最小的 \(x+y\) 满足 \(n-x|m+y\)。
多测,\(T\le 10^3,n,m\le 10^8\)。
分析
一个经典的错误做法是猜测 \(x\) 很小之类的。随便卡。考虑一些相对正确的做法。
首先有一个很显然的暴力:枚举 \(x\) 的值,那么最优的 \(y\) 显然可以 \(O(1)\) 求。然后也显然的死掉了。
看数据范围,猜测是个根号复杂度。考虑根号分治,设阈值 \(B=O(\sqrt V)\),若 \(n\le B\) 跑上述暴力,复杂度 \(O(\sqrt V)\)。\(n>B\) 时,我们需要注意到 \(m\le 2V\)(显然),若此时设 \(m+y=k(n-x)\),则 \(k\le O(\sqrt V)\),此时不难证明当 \(k(n-x)\) 减小到最靠近 \(m\) 且大于等于 \(m\) 的数是最优方案,也可以 \(O(1)\) 计算。复杂度 \(O(T\sqrt V)\)。
const int maxn=2e5+5,inf=0x3f3f3f3f,B=1e5,K=5e4;
const long long llinf=0x3f3f3f3f3f3f3f3f;
int n,m,ans;
inline void solve_the_problem(){
n=rd(),m=rd(),ans=inf;
if(n<=B){
rep(i,1,n)ckmn(ans,(m+i-1)/i*i-m+n-i);
}else{
rep(k,1,K){
if(1ll*n*k<m)continue;
int p=n-(m+k-1)/k;
ckmn(ans,1ll*k*(n-p)-m+p);
}
}
write(ans);
}

浙公网安备 33010602011771号