K-good(数论/取模运算/构造)

题目
题意:给定一个数 n < = 1 e 18 n<=1e18 n<=1e18,问是否存在一个数 k > = 2 k>=2 k>=2,使得 n n n可以由 k k k个 模 k k k意义下各不相等的正整数相加得到。
参考
思路:题意转化为给定 n n n,是否存在 k k k,使得 n = = k ∗ ( k + 1 ) / 2 + k ∗ x n==k*(k+1)/2+k*x n==k(k+1)/2+kx,其中 x > = 0 x>=0 x>=0 k k k个数在模 k k k意义下取值为 1 , 2 , . . . , k − 1 , k 1,2,...,k-1,k 1,2,...,k1,k,它们相加后为 k ∗ ( k + 1 ) / 2 k*(k+1)/2 k(k+1)/2,再加上若干个 k k k,即得到上式。
所以 n n n要满足两个条件:

  • n > = 1 + 2 + . . . + k = k ∗ ( k + 1 ) 2 n>=1+2+...+k=\frac{k*(k+1)}{2} n>=1+2+...+k=2k(k+1)
  • n = k ∗ ( k + 1 ) 2 ( % k ) n=\frac{k*(k+1)}{2}(\%k) n=2k(k+1)(%k)
    k k k为偶数时,上述第二式可以简化为 n = k 2 ( % k ) n=\frac{k}{2}(\% k) n=2k(%k),该式成立,当且仅当 2 ∗ n 2*n 2n k k k的倍数,而 n n n不是 k k k的倍数。且我们应该取最小的 k k k,为满足第一式,此时 k k k k 1 = 2 p + 1 k1=2^{p+1} k1=2p+1,其中 p p p n n n能整除2的最大次数。
    假如 k 1 k1 k1能满足第一式,则可以得到答案。
    如果 k 1 k1 k1不满足第一式,考虑 k 2 = 2 ∗ n k 1 k2=\frac{2*n}{k1} k2=k12n,根据 k 1 k1 k1的性质( 2 ∗ n 2*n 2n k 1 k1 k1的倍数,而 n n n不是 k 1 k1 k1的倍数),可得 k 2 k2 k2为奇数,且此时由 k 1 ∗ ( k 1 + 1 ) > 2 ∗ n = > k 2 < k 1 + 1 = > k 2 < = k 1 − 1 k1*(k1+1)>2*n=>k2<k1+1=>k2<=k1-1 k1(k1+1)>2n=>k2<k1+1=>k2<=k11。因此 k 2 ∗ ( k 2 + 1 ) 2 < = k 2 ∗ k 1 2 = n \frac{k2*(k2+1)}{2}<=\frac{k2*k1}{2}=n 2k2(k2+1)<=2k2k1=n,因此,此时 k 2 k2 k2能满足第一式。

综上, k 1 k1 k1 k 2 k2 k2至少有一个满足题意。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 200010;

ll n, k;

void solve() {
	scanf("%lld", &n);
	ll k2 = n;
	while (k2 % 2 == 0) {
		k2 /= 2;
	}
	if (k2 == 1) {
		printf("-1\n");
		return;
	}
	if (k2 <= 2e9 && (k2 + 1) / 2 * k2 <= n) {
		printf("%lld\n", k2);
	} else {
		printf("%lld\n", n / k2 * 2);
	}
}
int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		solve();
	}
}
/*
 k * (k - 1) / 2 + k * x == n
*/
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值