题意:

给定一个整数 \(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";
}
} }

最新文章

  1. 05.virsh命令的常用操作(kvm)
  2. USB协议规范学习(一)
  3. Codeforces Round #380 (Div. 2) 总结分享
  4. Clr静态数据Table-Valued函数
  5. MySQL sql语言的笔记
  6. 转:asmx迷10分钟升级成wcf熟手指南
  7. thinkphp URL相关
  8. Camera类
  9. ul ol 列表的样式的控制
  10. [MFC美化] MFC界面UI库总结
  11. Jenkins设置Poll SCM
  12. CBC翻转攻击(实验吧_简单的登陆题)
  13. 深入解剖unsigned int 和 int
  14. [BJOI2019]勘破神机
  15. Lodop打印维护PRINT_SETUP本地缓存ini文件
  16. 简单分析Java中审批业务流程业务原理
  17. Announcing HashiCorp Consul + Kubernetes
  18. 使用sqoop从Oracle或mysql抽取数据到HDFS遇到的报错及解决
  19. AIX 6.1记录
  20. embedded-redis在单元测试中的使用

热门文章

  1. go-micro集成RabbitMQ实战和原理
  2. OAuth2授权服务器Id Server一键生成配置原理
  3. Kafka 基础概念及架构
  4. 【系统】Windows相关软件下载
  5. 遍历list集合泛型为map
  6. C/C++ 单元自动化测试解决方案实践
  7. Egg上层框架CabloyJS是如何输出SQL语句日志的?
  8. Docker安装Jenkins打包Maven项目为Docker镜像并运行【保姆级图文教学】
  9. 基于数传电台的组态王控制实现远程采集控制器PLC
  10. Python双人五子棋