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;
}

posted on 2019-09-12 20:09  solvit  阅读(160)  评论(0编辑  收藏  举报

导航