zoukankan      html  css  js  c++  java
  • 莫队算法/二分查找 FZU 2072 Count

    题目传送门

    题意:问区间内x的出现的次数
    分析:莫队算法:用一个cnt记录x的次数就可以了。还有二分查找的方法

    代码:

    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    using namespace std;
    
    const int MAXN = 1e5 + 10;
    const int INF = 0x3f3f3f3f;
    struct Data
    {
        int b, l, r, x;
        int id;
    }data[MAXN];
    int a[MAXN];
    int cnt[MAXN];
    int ans[MAXN];
    int n, q;
    
    bool cmp(Data x, Data y)
    {
        if (x.b == y.b)    return x.r < y.r;
        return x.b < y.b;
    }
    
    void Modui(void)
    {
        memset (cnt, 0, sizeof (cnt));
    
        int l = 1, r = 0;
        for (int i=1; i<=q; ++i)
        {
            while (data[i].l < l)    cnt[a[--l]]++;
            while (data[i].l > l)    cnt[a[l]]--, l++;
            while (data[i].r > r)    cnt[a[++r]]++;
            while (data[i].r < r)    cnt[a[r]]--, r--;
    
            ans[data[i].id] = cnt[data[i].x];
        }
    
        for (int i=1; i<=q; ++i)
        {
            printf ("%d
    ", ans[i]);
        }
    }
    
    int main(void)        //FZU 2072 Count
    {
        while (scanf ("%d%d", &n, &q) == 2)
        {
            int block = (int) sqrt (n * 1.0);
            for (int i=1; i<=n; ++i)    scanf ("%d", &a[i]);
            for     (int i=1; i<=q; ++i)
            {
                scanf ("%d%d%d", &data[i].l, &data[i].r, &data[i].x);
                data[i].b = data[i].l / block;    data[i].id = i;
            }
    
            sort (data+1, data+1+q, cmp);
    
            Modui ();
        }
    
        return 0;
    }

    代码(二分查找):

    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <vector>
    using namespace std;
    
    const int MAXN = 1e5 + 10;
    const int INF = 0x3f3f3f3f;
    int a[MAXN];
    int n, q;
    vector<int> cnt[MAXN];
    
    int cal(int x, int r)
    {
        if (!cnt[x].size ())    return 0;
        int pos = upper_bound (cnt[x].begin (), cnt[x].end (), r) - cnt[x].begin () - 1;
        return pos;
    }
    
    int main(void)        //FZU 2072 Count
    {
    //    freopen ("A.in", "r", stdin);
    
        while (scanf ("%d%d", &n, &q) == 2)
        {
            for (int i=1; i<=n; ++i)
            {
                scanf ("%d", &a[i]);
            }
            for (int i=1; i<=n; ++i)    cnt[a[i]].clear ();
            for (int i=1; i<=n; ++i)    cnt[a[i]].push_back (i);
    
            for (int i=1; i<=q; ++i)
            {
                int l, r, x;    scanf ("%d%d%d", &l, &r, &x);
                printf ("%d
    ", cal (x, r) - cal (x, l - 1));
            }
        }
    
        return 0;
    }
    

      

    编译人生,运行世界!
  • 相关阅读:
    6、加法算术
    5、找出最大和最小的数
    4、计算并输出圆的面积和周长
    2、函数y=f(x)
    1、两数的平方和
    单片机中断寄存器知识点总结
    创建PCB原理图的模板
    电机知识
    结合实例谈谈航拍全景的方法和技巧
    航拍技巧
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4650189.html
Copyright © 2011-2022 走看看