HDU-6534-千佳とフレンドリーペア(Moのチームアルゴリズム、フェンウィックツリー、ディスクリート)

リンク:

https://vjudge.net/contest/308446#problem/C

質問の意味:

チカはあなたに整数列A1、A2、...、ANとm個のタスクを提供します。各タスクについて、あなたは一定の間隔で「友好ペア」の数を答える必要があります。

優しいペア:AIとAJ iがjで<とAI-AJの絶対値がある場合、2つの整数のために、与えられた整数定数K以下では、次いで、(I、J)は、「優しいペア」.A優しい対(呼び出されていません区間[L、R]でi、j)がL≤i<j≤Rを満たさなければなりません。

アイデア:

Moのアルゴリズムチーム、単にMoのチームは、最初のクエリ各変更位置を学習し、愚かな。
2つの配列の添字を持つ各位置照会レコードが。時間のオーバーヘッドを削減します。

コード:

#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\n", 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
*/

おすすめ

転載: www.cnblogs.com/YDDDD/p/11220560.html