#include<bits/stdc++.h>
using namespace std;
map<long long,long long> mp;
long long a[1000010];
//这道题n的大小不大,但a[i]的数值过大
//用数组存储会爆,所以使用STL容器map
int main(){
long long n,m;
cin>>n>>m;
//map的特点:
//1 创建 map<键值,映射值> 变量名
//2 键值不可重复,相当于数组的下标
//3 会自动按映射值从小到大排序
for(int i=1;i<=n;i++){
cin>>a[i];
mp[a[i]-m]++;//加入一个,变量名[键值]=映射值
//因为A+B=C,所以通过A-C来存储B对应的A的数量
}
long long ans=0;
for(int i=1;i<=n;i++){
ans+=mp[a[i]];//依次加入B对应的A的数量
}
cout<<ans;
//总结:
//map应用要用不同类型或大数来当数组下标的时候
//但自动排序的复杂度较高,n不能太大
return 0;
}
#include<bits/stdc++.h>
#include<algorithm>//使用函数要加此头文件
using namespace std;
long long a[200005];
int main(){
int n,c;
cin>>n>>c;
for(int i=1;i<=n;i++){
cin>>a[i];
}
long long cnt=0;
sort(a+1,a+n+1);
//lower_bound函数,查第一个大于等于x的位置(地址)
//lower_bound(起始位置(地址),终止位置(地址),x),可运用于数组
//upper_bound函数,查第一个大于x的位置
//upper_bound(起始位置(地址),终止位置(地址),x),可运用于数组
//!!!,因为lower_bound和upper_bound是二分查找,所以使用前一定要从小到大排序
for(int i=1;i<=n;i++){
if(a[i]<=c)continue;
//查找A-C的B有多少个,相当于有多少个A-B=C
long long u=upper_bound(a+1,a+n+1,a[i]-c)-lower_bound(a+1,a+n+1,a[i]-c);
//组合技巧:用第一个大于x的位置减第一个大于等于x的位置等于区间内有多少个x
if(u!=n+1){//如果区间内没有这个值,会返回最后一个元素的地址+数组大小
cnt+=u;
}
}
//lower_bound和upper_bound函数一开始都是返回目标(位置)地址,所以要输出下标时需要减去首地址。
//
cout<<cnt;
//总结:
//lower and upper 适用于快速多次查找元素
return 0;
}
//题目【P1102. A-B 数对】
#include<iostream>
#include<map>//使用函数前要导入此头文件
using namespace std;
//map的常用操作
int main(){
map<int,int> mp1;
//创建一个map:map<关键字(key),关键字的值(value)> 变量名
//map的功能:
//1.自动建立key和value的对应,key和value可为任意类型
//2.加入元素:mp1[键字(key)]=关键字的值(value)
mp1[1046]=1;
mp1[1014]=2;
mp1[1037]=2;
mp1[1058]=3;
mp1[1040]=1;
//3.查找元素:mp1[键字(key)],返回对应的关键字的值(value)
int x=mp1[1046];
cout<<x<<'\n';
//4.刪除与清空元素1
//删除元素:变量名.erase(要删除的元素)
mp1.erase(1014);
//清空元素1:变量名.erase(变量名.begin(),变量名.end())
//mp1.erase(mp1.begin(),mp1.end());
//5.map的大小:变量名.size()
int size1=mp1.size();
cout<<size1<<'\n';
//6.清空元素2:变量名.clear()
//mp.clear()
//7.指定元素出现的次数:变量名.count(指定元素)
cout<<mp1.count(1046)<<'\n';
return 0;
}