Chika and Friendly Pairs
Chika gives you an integer sequence a1,a2,…,an and m tasks. For each task, you need to answer the number of "
friendly pairs" in a given interval.
friendly pair: for two integers ai and aj, if i<j and the absolute value of ai−aj is no more than a given constant integer K, then (i,j) is called a “friendly pair”.A friendly pair (i,j) in a interval [L,R] should satisfy L≤i<j≤R.
Input
The first line contains 3 integers n (1≤n≤27000), m (1≤m≤27000) and K (1≤K≤109), representing the number of integers in the sequence a, the number of tasks and the given constant integer.
The second line contains n non-negative integers, representing the integers in the sequence a. Every integer of sequence a is no more than 109.
Then m lines follow, each of which contains two integers L, R (1≤L≤R≤n). The meaning is to ask the number of “friendly pairs” in the interval [L,R]。
Output
For each task, you need to print one line, including only
one integer, representing the number of “friendly pairs” in the query
interval.
题意:
求任意区间里面(a[i]-a[j])<k有多少对n个数,m次询问。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#define lowbits(x) x&(-x)
using namespace std;
const int N=3e4;
int sr[N],sl[N],sm[N],num[N],tr[N],cnt=0,k,sum[N],pox[N];
struct node{ //树状数组维护每一个莫队块中序列个数,前缀数组的作用;
int l,r,id,pot;
bool operator <(node a)const //预置排序;
{
return pot==a.pot?(pot&1?r<a.r:r>a.r):pot<a.pot;
}
}mp[N];
inline int read() //快读;
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
void update(int x, int val) //添加元素;
{
if(!x) return ;
while(x<N){
tr[x]+=val;
x+=lowbits(x);
}
}
int query(int x) //查询;
{
int ans=0;
while(x>0){
ans+=tr[x];
x-=lowbits(x);
}
return ans;
}
void add(int x) //上传数据,计算(num-k,num+k)的数据个数;
{
cnt+=(query(sr[x])-query(sl[x]));
update(sm[x],1);
}
void del(int x) //删除元素+减去个数;
{
update(sm[x],-1);
cnt-=(query(sr[x])-query(sl[x]));
}
int main()
{
int n,m,tot=1;
register int i; //加速运行,防止卡常;
//scanf("%d%d%d",&n,&m,&k);
n=read(),m=read(),k=read();
int block=(int)sqrt(n); //莫队分块,用于对输入排序;
for(i=1;i<=n;++i)
num[i]=read(),pox[i]=num[i];
for(i=0;i<m;++i){
mp[i].l=read();
mp[i].r=read();
mp[i].pot=mp[i].l/block;
mp[i].id=i;
}
sort(pox+1,pox+n+1);
sort(mp,mp+m);
for(i=2;i<=n;++i) //对数据离散化;
if(pox[i]!=pox[i-1]) pox[++tot]=pox[i];
for(i=1;i<=n;++i){
sl[i]=lower_bound(pox+1,pox+tot+1,num[i]-k)-pox-1; //取每一个数据的上下区间,方便后面的数据处理;
sr[i]=upper_bound(pox+1,pox+tot+1,num[i]+k)-pox-1;
sm[i]=lower_bound(pox+1,pox+tot+1,num[i])-pox;
}
int l=1,r=0;
for(i=0;i<m;++i){
while(r<mp[i].r) add(++r);
while(r>mp[i].r) del(r--);
while(l<mp[i].l) del(l++);
while(l>mp[i].l) add(--l);
sum[mp[i].id]=cnt; //记录结果;
}
for(i=0;i<m;++i){
printf("%d\n",sum[i]);
}
return 0;
}