CF1656D K-good
2024-09-06 11:59:41
题意:
给定一个整数 \(n\),请找出一个大于等于 \(2\) 的整数 \(k\),使得 \(n\) 可以表示成 \(k\) 个除以 \(k\) 的余数互不相同的数之和。
注意\(k\)个除以 \(k\) 的余数互不相同的数之和这一句话。容易想到,这就相当于是对 \(k\) 的一个完全剩余系求和使得和为 \(n\)。
因为除以 \(k\) 所能得到的余数只能为 \(0\) 到 \(k - 1\),并且,任意一个数减去余数部分,剩下的部分都可以被表示为 \(xk\),其中 \(x\) 为整数。
因此,我们设这些余数互不相同的数的和为 \(pk + \frac{k(k - 1)}{2}=n\)。有了这个式子,我们不难想到枚举 \(k\)并将结果与 \(n\) 进行比较,自然,收获TLE。
将柿子变形,又有:
\[k(2p + k - 1) = 2n
\]
\]
其中,\(2p\) 为偶数,\(k\) 和 \(k-1\) 各为偶数或奇数,易证, \(2n\) 为偶数,且 \(k\) 和 \((2p+k-1)\) 各有一个为奇数或偶数,且后者在题目情况中恒大于前者。
因此将 \(2n\) 进行分解,把它分解为一个 \(2\) 的次幂 \(a\) 和一个奇数 \(b\),因此得到这个柿子:
\[k = min(a,b)
\]
\]
AC代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
int k,n,t;
signed main(){
cin >> t;
while(t--){
cin >> n;
k = 2;
bool flag = 0;
int j = 1;
n *= 2;
while(n % 2 == 0){
j *= 2;
n /= 2;
}
if(n == 1){
cout << "-1\n";
}
else{
cout << min(n,j) << "\n";
}
}
}
最新文章
- 05.virsh命令的常用操作(kvm)
- USB协议规范学习(一)
- Codeforces Round #380 (Div. 2) 总结分享
- Clr静态数据Table-Valued函数
- MySQL sql语言的笔记
- 转:asmx迷10分钟升级成wcf熟手指南
- thinkphp URL相关
- Camera类
- ul ol 列表的样式的控制
- [MFC美化] MFC界面UI库总结
- Jenkins设置Poll SCM
- CBC翻转攻击(实验吧_简单的登陆题)
- 深入解剖unsigned int 和 int
- [BJOI2019]勘破神机
- Lodop打印维护PRINT_SETUP本地缓存ini文件
- 简单分析Java中审批业务流程业务原理
- Announcing HashiCorp Consul + Kubernetes
- 使用sqoop从Oracle或mysql抽取数据到HDFS遇到的报错及解决
- AIX 6.1记录
- embedded-redis在单元测试中的使用