zoukankan      html  css  js  c++  java
  • HDU-6534-Chika and Friendly Pairs (莫队算法,树状数组,离散化)

    链接:

    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
    */
    
  • 相关阅读:
    java简单实现MD5加密
    Java用freemarker导出Word 文档
    java 反射(*)
    java解析XML
    JDBC程序实例
    web前端开发-博客目录
    虚拟主机配置
    WAMP运行原理
    WAMP配置
    web前端性能优化总结
  • 原文地址:https://www.cnblogs.com/YDDDD/p/11220560.html
Copyright © 2011-2022 走看看