895B - XK Segments

time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

While Vasya finished eating his piece of pizza, the lesson has already started. For being late for the lesson, the teacher suggested Vasya to solve one interesting problem. Vasya has an array a and integer x. He should find the number of different ordered pairs of indexes (i, j) such that ai ≤ aj and there are exactly k integers y such that ai ≤ y ≤ aj and y is divisible by x.

In this problem it is meant that pair (i, j) is equal to (j, i) only if i is equal to j. For example pair (1, 2) is not the same as (2, 1).

Input

The first line contains 3 integers n, x, k (1 ≤ n ≤ 105, 1 ≤ x ≤ 109, 0 ≤ k ≤ 109), where n is the size of the array a and x and k are numbers from the statement.

The second line contains n integers ai (1 ≤ ai ≤ 109) — the elements of the array a.

Output

Print one integer — the answer to the problem.

Examples
Input
4 2 1
1 3 5 7
Output
3
Input
4 2 0
5 3 1 7
Output
4
Input
5 3 1
3 3 3 3 3
Output
25
Note

In first sample there are only three suitable pairs of indexes — (1, 2), (2, 3), (3, 4).

In second sample there are four suitable pairs of indexes(1, 1), (2, 2), (3, 3), (4, 4).

In third sample every pair (i, j) is suitable, so the answer is 5 * 5 = 25.

暴力会超时

从a[i]开始x的第一个倍数是f=l*x;其中l=a[i]/x+(a[i]%x!=0)

第k个倍数就是f1=f+(k-1)x;

第k+1个倍数是f2=f1+x;

从a[i]到符合条件的a[j]的j的取值范围是[f1,f2);

【一个数组number序列为:4,10,11,30,69,70,96,100.设要插入数字3,9,111.pos为要插入的位置的下标,则:

pos = lower_bound( number, number + 8, 3) - number,pos = 0.即number数组的下标为0的位置。

pos = lower_bound( number, number + 8, 9) - number, pos = 1,即number数组的下标为1的位置(即10所在的位置)。

pos = lower_bound( number, number + 8, 111) - number, pos = 8,即number数组的下标为8的位置(但下标上限为7,所以返回最后一个元素的下一个元素)。

所以,要记住:函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置,且last的位置是越界的!!~】、

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
const int N=1e5+1e3+7;
long long n,k,x,a[N],ans;

int main()
{
    cin>>n>>x>>k;
    for(int i=0;i<n;i++)
        scanf("%I64d",&a[i]);
    sort(a,a+n);
    for(int i=0;i<n;i++)
    {
        long long l=a[i]/x+(a[i]%x!=0);//第一个x的倍数是l*x;(a[i]%x!=0)就是a[i]%x!=0时返回1,否则返回0
        long long f1=(l+k-1)*x;//第k个x的倍数
        long long f2=f1+x;//第K+1个x的倍数
        //所以从a[i]到符合条件的a[j]的j的取值范围是[f1,f2)
//        printf("f1=%lld f2=%lld\n",f1,f2);
        if(k==0)
        {
            f1=a[i];
            f2=l*x;
        }
//        printf("位置f2=%d  ",lower_bound(a,a+n,f2)-a);//f2在数组a中的位置
//        printf("位置f1=%d\n",lower_bound(a,a+n,f1)-a);
        ans+=lower_bound(a,a+n,f2)-lower_bound(a,a+n,f1);
    }
    printf("\n%I64d\n",ans);
    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 线段相交问题是计算几何学中的常见问题,主要目标是确定两个给定线段是否相交。在解决这个问题时,我们可以使用几何知识和数学方法,下面是一种常见的解决方案: 首先,我们可以将每个线段表示为两个端点的坐标。对于线段AB,我们可以表示为A(x1, y1)和B(x2, y2)。同样的,对于线段CD,我们可以表示为C(x3, y3)和D(x4, y4)。 然后,我们可以利用一系列关系来判断线段是否相交。首先,我们可以通过比较两个线段的最小和最大x坐标来判断它们是否在同一平面上。如果线段AB的最小x坐标大于线段CD的最大x坐标,或者线段AB的最大x坐标小于线段CD的最小x坐标,则可以判断它们不会相交。 接下来,我们可以利用向量的叉积来判断两个线段是否共线。我们可以计算向量AB和向量AC的叉积以及向量CD和向量CA的叉积。如果这两个叉积乘积小于0,则可以判断线段AB和线段CD相交。 最后,我们需要考虑一些特殊情况,例如两个线段共线但没有重叠部分的情况,或者两个线段有一个公共端点的情况。这些情况可以通过包含更多的条件来进一步判断。 通过以上的方法,我们可以相对准确地判断两个线段是否相交。这个问题在计算几何学和计算机图形学中有广泛的应用,例如在碰撞检测、路径规划和游戏开发中都可以使用到。 ### 回答2: line-segments-intersect是一个用于确定两个线段是否相交的算法。这个算法的目标是判断给定的两个线段是否存在交点,若存在,则认为两个线段相交,否则认为它们不相交。 这个算法可以通过以下步骤来实现: 1. 首先,我们需要确定每个线段的两个端点的坐标。假设第一个线段的端点分别为A(x1, y1)和B(x2, y2),第二个线段的端点分别为C(x3, y3)和D(x4, y4)。 2. 接下来,我们需要利用线段AB的斜率和CD的斜率来判断它们是否平行。如果两条线段的斜率相等,那么它们是平行的,此时它们不会相交。 3. 如果线段AB和CD不平行,我们进一步判断它们是否相交。我们可以使用线段的方程来计算两条线段的交点。如果两条线段的交点的x坐标和y坐标都在两个线段的范围内,则认为它们相交。 4. 如果以上条件都不满足,则认为两条线段不相交。 通过以上步骤,我们可以确定两个线段是否相交。这个算法可以在计算机程序中实现,并可以用于各种应用场景,如计算几何问题、计算路径交叉等。但需要注意的是,线段的相交判断需要考虑特殊情况,如端点重合、线段长度为0等,以保证算法的准确性和稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值