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;
}
浙公网安备 33010602011771号