K-good(奇偶性构造)

K-good

[Link](Problem - D - Codeforces)

题意

给你一个数 n n n,问你能否将起拆成 k k k个数,这 k k k个数和为 n n n m o d   k mod\ k mod k的值各不相同。

思路

​ 也就是余数为 0 , 1 , . . . , k − 1 0,1,...,k-1 0,1,...,k1将其转化为数学式子,即 n − k ( k − 1 ) / 2 ≡ 0 ( m o d   k ) n-k(k-1)/2 \equiv 0 (mod\ k) nk(k1)/20(mod k),由于要是 k k k个正整数的和因此将余数 0 0 0转变为 k k k,即需满足 n − k ( k + 1 ) / 2 ≡ 0 ( m o d k )   且 k ≥ 2 n-k(k+1)/2 \equiv 0(mod k)\ 且k\ge 2 nk(k+1)/20(modk) k2

​ 如果 k k k是奇数一定且满足 k ( k + 1 ) / 2 ≤ n k(k+1)/2\le n k(k+1)/2n成立,如果 k k k是偶数且 k ( 2 k + 1 ) ≤ n k(2k+1)\le n k(2k+1)n也成立,奇数显然成立,偶数的话 n − k ( k + 1 ) / 2 ≡ 0 ( m o d   k ) n-k(k+1)/2\equiv 0(mod\ k) nk(k+1)/20(mod k)是不一定成立的,但 n − 2 k ( 2 k + 1 ) ≡ 0 ( m o d   k ) n-2k(2k+1)\equiv0(mod\ k) n2k(2k+1)0(mod k)一定成立。

​ 特殊构造一下将 n n n分解为 2 k × t 2^k\times t 2k×t的形式其中 t t t是奇数,则要不然就是 2 k 2^k 2k成立,要不然就是 t t t成立,若 t = = 1 t==1 t==1 2 k 2^k 2k不成立则无解。

Code

#include <bits/stdc++.h>
#define x first
#define y second
#define debug(x) cout<<#x<<":"<<x<<endl;
using namespace std;
typedef long double ld;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef unsigned long long ULL;
const int N = 1e5 + 10, M = 2 * N, INF = 0x3f3f3f3f, mod = 1e9 + 7;
const double eps = 1e-8, pi = acos(-1), inf = 1e20;
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int h[N], e[M], ne[M], w[M], idx;
void add(int a, int b, int v = 0) {
    e[idx] = b, w[idx] = v, ne[idx] = h[a], h[a] = idx ++;
}
LL n, m, k;
int a[N];
void solve() {
    cin >> n;
    m = n, k = 1;
    while (m % 2 == 0) m /= 2, k <<= 1;
    
    if (k <= 1e9 && k * (2 * k + 1) <= n) {
        cout << k * 2 << '\n';
        return ;
    }
    if (m != 1 && m <= 2e9 && m * (m + 1) / 2 <= n) {
        cout << m << '\n';
        return ;
    }

    cout << -1 << '\n';
}
int main() {
    ios::sync_with_stdio(false), cin.tie(0);
    int T;
    cin >> T;
    while (T -- ) {
        solve();
    }
    return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值