P1102 A-B 数对

# A-B 数对

## 题目背景

出题是一件痛苦的事情!

相同的题目看多了也会有审美疲劳,于是我舍弃了大家所熟悉的 A+B Problem,改用 A-B 了哈哈!

## 题目描述

给出一串正整数数列以及一个正整数 $C$,要求计算出所有满足 $A - B = C$ 的数对的个数(不同位置的数字一样的数对算不同的数对)。

## 输入格式

输入共两行。

第一行,两个正整数 $N,C$。

第二行,$N$ 个正整数,作为要求处理的那串数。

## 输出格式

一行,表示该串正整数中包含的满足 $A - B = C$ 的数对的个数。

## 样例 #1

### 样例输入 #1

```
4 1
1 1 2 3
```

### 样例输出 #1

```
3
```

## 提示

对于 $75\%$ 的数据,$1 \leq N \leq 2000$。

对于 $100\%$ 的数据,$1 \leq N \leq 2 \times 10^5$,$0 \leq a_i <2^{30}$,$1 \leq C < 2^{30}$。

2017/4/29 新添数据两组

 

#include <bits/stdc++.h>
#define fi first
#define se second 
using namespace std;
const int N=2e5+10; 
const int M=2e5+10;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
typedef long long LL;
typedef pair<int,int>PII;
typedef pair<LL,LL>PLL;
LL gcd(LL a,LL b) {return b?gcd(b,a%b):a;}
LL lcm(LL a,LL b) {return a/gcd(a,b)*b;}
LL lowbit(LL a){return a&-a;}
//8个方向的和4个方向的是不同的计算方法
int n,c; 
LL a[N];
LL res;
LL cnt(int x,int k)
{

	int cnt1=0,cnt2=0;
	int l=1,r=n;

	//第一个大于等于x的位置下标 
	while(l<r)
	{
		int mid=l+r>>1;//因为没有交换,所以不用存数值 
		if(a[mid]>=x)r=mid;
		else l=mid+1;
	}
	cnt1=l;
	//最后 一个小于等于它的 
	l=1,r=n;
	while(l<r)
	{
		int mid=l+r+1>>1;
		if(a[mid]<=x)l=mid;
		else r=mid-1;
	}
	cnt2=r;

	if(cnt1>cnt2||a[cnt1]!=x)return 0;
	
	if(cnt1<=k&&k<=cnt2) return cnt2-cnt1;
    else return cnt2-cnt1+1;

	//r减去了1 所以 加一,没有减去就不用加了 
}
int main()
{
    scanf("%d%d",&n,&c);
    for(int i=1;i<=n;i++)
    scanf("%lld",&a[i]);
    
    sort(a+1,a+n+1);
    
    for(int i=n;i>=1;i--)
    {
		if(a[i]<c)break;
		res+=cnt(a[i]-c,i);
	}
    cout<<res<<endl;
    return 0;
}

 

posted on 2022-10-17 21:36  浅唱\,,笑竹神易  阅读(190)  评论(0)    收藏  举报