HDU6534 Chika and Friendly Pairs(莫队,树状数组)
HDU6534 Chika and Friendly Pairs
莫队,树状数组的简单题
#include<bits/stdc++.h>
using namespace std;
const int maxn = 30005;
const int maxq = 27005;
int n, m, k, num, sz, len;
int a[maxn], belong[maxn], t[maxn], tree[maxn], ans[maxq];
int lowerl[maxn], lowerr[maxn], lower[maxn];
struct Q{
int l ,r, id;
}query[maxq];
int cmp(Q a, Q b){
return (belong[a.l] ^ belong[b.l]) ? belong[a.l] < belong[b.l] : ((belong[a.l] & 1) ? a.r < b.r : a.r > b.r);
}
void init()
{
for(int i = 1; i <= n; i++) t[i] = a[i];
sort(t + 1, t + n + 1);
len = unique(t + 1, t + n + 1) - (t + 1);
for(int i = 0; i <= len; i++) tree[i] = 0;
}
int _hash(int x)
{
return lower_bound(t + 1, t + len + 1, x) - t;
}
inline int lowbit(int x){return x & (-x);}
void update(int pos, int x)
{
if(pos < 1) return;
while(pos <= len + 1){
tree[pos] += x;
pos += lowbit(pos);
}
}
int query_ans(int pos)
{
int ret = 0;
while(pos >= 1){
ret += tree[pos];
pos -= lowbit(pos);
}
return ret;
}
int main()
{
while(~scanf("%d%d%d", &n, &m, &k)){
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
sz = sqrt(n);
num = ceil((double)n / sz);
for(int i = 1; i <= num; i++){
for(int j = (i - 1) * sz + 1; j <= i * sz && j <= n; j++){
belong[j] = i;
}
}
for(int i = 1; i <= m; i++){
scanf("%d%d", &query[i].l, &query[i].r);
query[i].id = i;
}
init();
sort(query + 1, query + m + 1, cmp);
int l = 1, r = 0;
int now = 0;
for(int i = 1; i <= n; i++){
lowerl[i] = _hash(a[i] - k);
lowerr[i] = _hash(a[i] + k);
lower[i] = _hash(a[i]);
}
for(int i = 1; i <= m; i++){
int ql = query[i].l, qr = query[i].r;
while(l < ql){
int lid = lowerl[l], rid = lowerr[l], id = lower[l];
lid--;
if(t[rid] > a[l] + k) rid--;
update(id, -1);
now -= (query_ans(rid) - query_ans(lid));
l++;
}
while(l > ql){
l--;
int lid = lowerl[l], rid = lowerr[l], id = lower[l];
lid--;
if(t[rid] > a[l] + k) rid--;
now += (query_ans(rid) - query_ans(lid));
update(id, 1);
}
while(r < qr){
r++;
int lid = lowerl[r], rid = lowerr[r], id = lower[r];
lid--;
if(t[rid] > a[r] + k) rid--;
now += (query_ans(rid) - query_ans(lid));
update(id, 1);
}
while(r > qr){
int lid = lowerl[r], rid = lowerr[r], id = lower[r];
lid--;
if(t[rid] > a[r] + k) rid--;
update(id, -1);
now -= (query_ans(rid) - query_ans(lid));
r--;
}
ans[query[i].id] = now;
}
for(int i = 1; i <= m; i++){
printf("%d\n", ans[i]);
}
}
return 0;
}