题解 [CF1656D] K-good
个人感觉还是挺有思维难度的
首先发现 \(n\) 为奇数时答案为 2
然后发现就是要找
\[n\equiv 0\pmod k(2\nmid k)
\]
\[n\equiv \frac{k}{2}\pmod k(2\mid k)
\]
同时还要满足 \(\frac{k(k+1)}{2}\leqslant n\),称为条件 1
打表发现 \(n=2^t\) 时无解
然后就只会到根号复杂度了
正解感觉是个无意义比较巧合的结论
考虑 \(\max \{t\mid 2^t|n\}\)
若这个 \(2^t\) 满足条件 1,那么输出即可
否则考虑 \(k_2=\frac{n}{2^{t-1}}=\frac{2n}{k_1}\),令 \(k_1=2^t\)
有 \(\frac{k_1(k_1+1)}{2}> n\),那么移项得 \(k_2<k_1+1\),而 \(k_2\) 为奇数,所以 \(k_2<k_1\)
发现 \(\frac{k_2(k_2+1)}{2}\leqslant \frac{k_2k_1}{2}=n\)
所以这个 \(k_2\) 一定合法,输出即可
并不知如何找到这样的性质
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define ll long long
#define int long long
char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
int ans=0, f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
return ans*f;
}
int n;
signed main()
{
int T=read();
while (T--) {
n=read();
if (__builtin_popcountll(n)==1) {puts("-1"); continue;}
__int128 i=2;
while (n%i==0) i<<=1;
if (i*(i+1)/2<=n) printf("%lld\n", (ll)i);
else printf("%lld\n", (ll)(2*n/i));
}
return 0;
}