CF895B XK Segments 题解

CF895B XK Segments 题解

题目描述

CF895B XK Segments

题目解法

朴素想法

最简单的想法就是枚举二元组 (i,j) 的第一项 i,然后再枚举 j,找到一个满足条件的 aj,然后更新答案。

很明显,该做法的时间复杂度为 O(n2),无法通过本题。

二分

我们发现,a 数组不会更改,并且每次枚举 aj 的过程相当于查找符合条件的区间中元素的个数。

先算出大于等于 ai 的第一个 x 的倍数 ai

{ai=(aix+1)×x(ai0modx)ai=ai(ai0modx)

符合条件的区间的左端点 l=ai+(k1)×x

符合条件的区间的右端点 r=ai+k×x

记得特判 k=0 的情况。

先排序再二分端点,迭代器相减即可。

记得开 long long

Code

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n, x, k;
vector<int> vc;
signed main()
{
cin>>n>>x>>k;
int ans=0;
for(int i=1, v;i<=n;i++)
cin>>v, vc.push_back(v);
sort(vc.begin(), vc.end());
for(auto i:vc)
{
int nx=(i%x)?(i/x+1)*x:i;
int l=k?nx+(k-1)*x:i, r=nx+k*x;
auto it1=lower_bound(vc.begin(), vc.end(), r);
auto it2=lower_bound(vc.begin(), vc.end(), l);
ans+=it1-it2;
}
cout<<ans;
}

本文作者:Jimmy-LEEE

本文链接:https://www.cnblogs.com/redacted-area/p/18379521

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Jimmy-LEEE  阅读(8)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起