题目地址

题目简译:给定\(n\)个等差数列,每个等差数列的起点为\(s\),终点为\(e\),差为\(d\)。整个序列中至多有一个位置所占数字是奇数。判断奇数位是否存在,如果不存在输出"There's no weakness.",如果存在输出位置与大小。

温馨提示:\(⌊x⌋\)为将\(x\)向下取整

算法:前缀和 + 二分位置

1、奇数位存在性

整个序列中至多有一个位置的数字所占数量是奇数,所以如果存在奇数位,则整个数列的总和必然是奇数(奇数 + 偶数 = 奇数,偶数 + 偶数 = 偶数)。反之,若不存在奇数位,则一定是偶数。故只需判断数字数量的总和的奇偶性即可。

2、二分位置

若存在这个奇偶性,我们可以通过二分答案的位置来找到这个位置,然后判断区间\([l,mid]\)的总和的奇偶性。若为奇数,则奇数位存在于此区间。反之若为偶数,则一定存在于\([mid+1,r]\)区间。用这个方法逐步缩小范围即可。

关于查找\([l,mid]\)的总和,我们可以用前缀和的思路,用\(sum[n] - sum[mid-1]\)即可求出。(\(sum[i]\)为求出\(i\)位置之前所有位置的和)

3、\(O(n)\)时间求出区间\(sum[x]\)的数字个数

设整个数列的最小位置为\(minn\)

这里,我们枚举每一个等差数列(它的起点为\(s\),终点为\(e\),差为\(d\))。若\(s <= x\),则两区间存在交集。

则它与\([minn,x]\)的共同区间为\([s,min(e,x)]\)。那么此区间包含此数列的个数是\((⌊(min(e,x) - s) / d⌋ + 1\)。

正确性证明十分容易:

在此区间中存在一段区间,共\(⌊s,min(e,x) / d⌋ * d\)个位置,头尾的位置上都有数字,差为\(d\),则数字的数量就是\((⌊(min(e,x) - s) / d⌋ + 1\)。

时间复杂度:\(O(nlogn)\)

二分的时间为\(O(logn)\),每次\(check()\)的时间为\(O(n)\),故总的时间复杂度为\(O(nlogn)\)。

C++ 代码

#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
const int N = 200000 + 1, INF = 1e9;
int t,n;
struct node{
int s,e,d;
}a[N];
int getSum(int x){ // O(n) 求[1,x]的前缀和
int res = 0;
for(int i = 1; i <= n; i++)
if(a[i].s <= x)
res += (min(a[i].e, x) - a[i].s)/a[i].d + 1; return res;
}
bool check(int l,int r){ // O(n) 查找[l,r]是否存在奇数位
return (getSum(r) - getSum(l - 1)) & 1;
}
int main(){
cin >> t;
while(t--){
cin >> n;
int maxn = -INF, minn = INF;
for(int i = 1; i <= n; i++){
cin >> a[i].s >> a[i].e >> a[i].d;
minn = min(minn,a[i].s);
maxn = max(maxn,a[i].e);
} if(!(getSum(maxn) & 1)){
cout << "There's no weakness." << endl;
}else{
int l = minn, r = maxn;
while(l <= r){
int mid = (l + r) >> 1;
if(check(l,mid))r = mid - 1;
else l = mid + 1;
} cout << l << " " << (getSum(l) - getSum(l - 1)) << endl;
}
}
return 0;
}

最新文章

  1. Openwrt 编译报错:rootfs image is too big解决方法
  2. 【转载】STL&quot;源码&quot;剖析-重点知识总结
  3. POJ 1001 Exponentiation(JAVA,BigDecimal-&gt;String)
  4. 二手奢侈品电商Vestiaire Collective融资2000万美元
  5. C#操作Excel开发报表系列整理(转)
  6. postGreSQL数据库部署及简单使用
  7. js 里面 写 C# 代码 遇到的问题
  8. js动态加载的蒙板弹框
  9. spring学习笔记1
  10. iOS动画学习 -隐式动画
  11. vue-router 组件复用问题
  12. 10_27_unittest
  13. [网络流]Farm Tour(费用流
  14. C/C++和Lua是如何进行通信的?
  15. djjango cookie和session 的几种常用需求使用方法
  16. 本地开启apache虚拟服务器
  17. Dell H300/6i/6iR/H700/H800阵列卡配置(转)
  18. Android之文件搜索工具类
  19. Day 34 面试题
  20. 20145328 《Java程序设计》第5周学习总结

热门文章

  1. 关闭防火墙和设置主机名和ip及克隆机网卡处理方法
  2. linux文本模式和文本替换功能
  3. Notepad++安装教程
  4. python学习--sys.argv
  5. Mesos Marathon能做什么?理念是什么?(转)
  6. git 最新笔记,工作中的必会技能
  7. Redis安全学习
  8. Python相比其他计算机语言真的更有优势吗?
  9. 面经分享!蚂蚁金服三面被拒,重拾起鼓四面猿辅导成功拿下offer!
  10. java后端开发三年!你还不了解Spring 依赖注入,凭什么给你涨薪