链接:
https://vjudge.net/contest/308446#problem/C
题意:
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.
思路:
莫队算法,刚学的莫队,第一每次更改都查询位置,太蠢了.
用两个数组记录每个位置查询的下标.减少时间开销.
代码:
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 3e4+10;
struct Node
{
int l, r;
int pos;
}node[MAXN];
int Tree[MAXN];
int a[MAXN], b[MAXN];
int L[MAXN], R[MAXN], P[MAXN];
int Res[MAXN];
int n, m, k;
int pos;
int l, r, res;
int unit;
int Lowbit(int x)
{
return (-x)&x;
}
void AddTree(int x, int v)
{
while (x <= n)
{
Tree[x] += v;
x += Lowbit(x);
}
}
int GetSum(int x)
{
int sum = 0;
while (x > 0)
{
sum += Tree[x];
x -= Lowbit(x);
}
return sum;
}
void Add(int x)
{
int rsum = GetSum(R[x]);
int lsum = GetSum(L[x]);
res += rsum-lsum;
AddTree(P[x], 1);
}
void Del(int x)
{
AddTree(P[x], -1);
int rsum = GetSum(R[x]);
int lsum = GetSum(L[x]);
res -= rsum - lsum;
}
void Query(int ql, int qr)
{
while (l < ql)
Del(l++);
while (l > ql)
Add(--l);
while (r < qr)
Add(++r);
while (r > qr)
Del(r--);
}
bool cmp(Node& a, Node& b)
{
if (a.l/unit != b.l/unit)
return a.l/unit < b.l/unit;
return a.r < b.r;
}
int main()
{
scanf("%d %d %d", &n, &m, &k);
unit = sqrt(n);
for (int i = 1;i <= n;i++)
{
scanf("%d", &a[i]);
b[i] = a[i];
}
for (int i = 1;i <= m;i++)
scanf("%d %d", &node[i].l, &node[i].r), node[i].pos = i;
sort(b+1, b+1+n);
pos = unique(b+1, b+1+n)-b;
for (int i = 1;i <= n;i++)
{
P[i] = lower_bound(b+1, b+pos, a[i])-b;
R[i] = lower_bound(b+1, b+pos, a[i]+k)-b;
if (b[R[i]] != a[i]+k)
R[i]--;
L[i] = lower_bound(b+1, b+pos, a[i]-k)-b-1;
}
sort(node+1, node+1+m, cmp);
l = 1, r = 0;
for (int i = 1;i <= m;i++)
{
Query(node[i].l, node[i].r);
Res[node[i].pos] = res;
}
for (int i = 1;i <= m;i++)
printf("%d
", Res[i]);
return 0;
}
/*
7 2 3
2 5 7 5 1 5 6
6 6
1 3
4 6
2 4
3 4
7 2 3
2 5 7 5 1 5 6
1 3
4 6
*/