codeforces895B XK segments
2017-12-15 22:45
106 查看
蛮有趣的一道题。
先来说说题意,大概是:对一个数组a,定义符合条件的二元组(i,j)表示恰好存在k个整数,满足ai≤y≤aj且y为x的倍数,求符合条件的二元组数量。
一上来有些懵逼,不妨先找找规律。
我们知道,假定存在k个这样的整数,那么首先[L,L+(k−1)∗x]一定是符合条件的一个区间,然后考虑拓展,右端点范围应当是[L+(k−1)∗x,L+k∗x−1],因为这个时候一定能找到符合条件的k个整数。
接下来的问题就是如何找到L。假如a[i]不是x的倍数,那么a[i]本身不会算到k个数中间去,所以此时L=(a[i]/x+1)∗x;否则,a[i]也是k的一份子,所以L=a[i]。
对数组排序之后,我们可以遍历一遍整个数组,然后对每一个数求一下在[L+(k−1)∗x,L+k∗x−1]范围内有多少数即可。
最后考虑如何实现。由于我们只是统计个数,所以我们可以二分查找出l=L+(k−1)∗x,r=L+k∗x第一个大于等于这两个数的数所在的位置相减即可。可以采用algorithm库的lower_bound实现。
当然这样有个问题,就是对k = 0的情况应当有一些特判,此时我们发现如果a[i]是x的倍数,区间就是a[i],a[i]那么结果为0,而此时L=a[i];否则区间应当是a[i],L,此时由于k=0所以L=r,所以只需要对l加一个特判即可。
AC代码:
先来说说题意,大概是:对一个数组a,定义符合条件的二元组(i,j)表示恰好存在k个整数,满足ai≤y≤aj且y为x的倍数,求符合条件的二元组数量。
一上来有些懵逼,不妨先找找规律。
我们知道,假定存在k个这样的整数,那么首先[L,L+(k−1)∗x]一定是符合条件的一个区间,然后考虑拓展,右端点范围应当是[L+(k−1)∗x,L+k∗x−1],因为这个时候一定能找到符合条件的k个整数。
接下来的问题就是如何找到L。假如a[i]不是x的倍数,那么a[i]本身不会算到k个数中间去,所以此时L=(a[i]/x+1)∗x;否则,a[i]也是k的一份子,所以L=a[i]。
对数组排序之后,我们可以遍历一遍整个数组,然后对每一个数求一下在[L+(k−1)∗x,L+k∗x−1]范围内有多少数即可。
最后考虑如何实现。由于我们只是统计个数,所以我们可以二分查找出l=L+(k−1)∗x,r=L+k∗x第一个大于等于这两个数的数所在的位置相减即可。可以采用algorithm库的lower_bound实现。
当然这样有个问题,就是对k = 0的情况应当有一些特判,此时我们发现如果a[i]是x的倍数,区间就是a[i],a[i]那么结果为0,而此时L=a[i];否则区间应当是a[i],L,此时由于k=0所以L=r,所以只需要对l加一个特判即可。
AC代码:
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; typedef long long LL; LL a[100003], ans; int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); LL n, x, k; cin>>n>>x>>k; for(int i = 1; i <= n; ++i) cin>>a[i]; sort(a + 1, a + n + 1); for(int i = 1; i <= n; ++i) { LL L = (a[i] % x) ? ((a[i] / x + 1) * x) : a[i]; LL l = L + (k - 1) * x, r = L + k * x; if(!k) l = a[i]; ans += lower_bound(a + 1, a + n + 1, r) - lower_bound(a + 1, a + n + 1, l); } cout<<ans<<endl; return 0; }
相关文章推荐
- C++二分查找在搜索引擎多文档求交的应用分析
- C语言数据结构中二分查找递归非递归实现并分析
- C++ 中二分查找递归非递归实现并分析
- C语言编程中实现二分查找的简单入门实例
- C#二分查找算法实例分析
- JavaScript实现二分查找实例代码
- JS二分查找算法详解
- 浅谈选择、冒泡排序,二分查找法以及一些for循环的灵活运用
- 二分查找算法在C/C++程序中的应用示例
- C++二分查找(折半查找)算法实例详解
- PHP二分查找算法的实现方法示例
- PHP二分查找算法示例【递归与非递归方法】
- php实现的二分查找算法示例
- js基本算法:冒泡排序,二分查找的简单实例
- 在MySQL中实现二分查找的详细教程
- C++二分查找算法实例
- java 算法二分查找和折半查找
- Java实现二分查找的变种
- 详解Java数据结构和算法(有序数组和二分查找)
- Java实现二分查找算法实例分析