zoukankan      html  css  js  c++  java
  • LOJ#6285. 数列分块入门 9

    有点难.....

    要求区间众数,所以我可以先把区间分块,然后我预处理出从第 i 块到第 j 块的众数,用dp[i][j]记录下来。

    因为需要知道众数的num值, 所以我可以用一个vector来保存每个数的所有的出现位置,然后我待会我查询的时候就查询我所需要的[l, r]中有多少个这个数。

    所以要求区间众数的时候,我可以通过之前打表的dp找出这中间完整的块的众数,然后对于边上的不完整的块,直接暴力扫过去,然后找最大的就可以了

    #include<map>
    #include<set>
    #include<ctime>
    #include<cmath>
    #include<stack>
    #include<queue>
    #include<string>
    #include<vector>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define first fi
    #define second se
    #define lowbit(x) (x & (-x))
    
    typedef unsigned long long int ull;
    typedef long long int ll;
    const double pi = 4.0*atan(1.0);
    const int inf = 0x3f3f3f3f;
    const int maxn = 100000;
    const int maxm = 400;
    const int mod = 10007;
    using namespace std;
    
    int n, m, tol, T;
    int block;
    int a[maxn];
    int b[maxn];
    int cnt[maxn];
    int belong[maxn];
    int dp[maxm][maxm];
    vector<int> v[maxn];
    
    void init() {
    
    }
    
    int L(int x) {
        return (x-1) * block + 1;
    }
    
    int R(int x) {
        return min(n, x*block);
    }
    
    void handle(int x) {
        int ans = 0;
        int num = 0;
        memset(cnt, 0, sizeof cnt);
        for(int i=L(x); i<=n; i++) {
            cnt[a[i]]++;
            if(cnt[a[i]] > ans) {
                num = a[i];
                ans = cnt[a[i]];
            }
            if(cnt[a[i]] == ans && a[i] < num) {
                num = a[i];
                ans = cnt[a[i]];            
            }
            dp[x][belong[i]] = num;
        }
    }
    
    int solve(int l, int r, int x) {
        return upper_bound(v[x].begin(), v[x].end(), r) - lower_bound(v[x].begin(), v[x].end(), l);
    }
    
    int query(int l, int r) {
        int num = dp[belong[l]+1][belong[r]-1];
        int ans = solve(l, r, num);
        for(int i=l; i<=min(r, R(belong[l])); i++) {
            int t = solve(l, r, a[i]);
            if(t > ans) {
                ans = t;
                num = a[i];
            }
            if(t == ans && a[i] < num) {
                ans = t;
                num = a[i];            
            }
        }
        if(belong[l] == belong[r])    return num;
        for(int i=L(belong[r]); i<=r; i++) {
            int t = solve(l, r, a[i]);
            if(t > ans) {
                ans = t;
                num = a[i];
            }
            if(t == ans && a[i] < num) {
                ans = t;
                num = a[i];            
            }        
        }
        return num;
    }
    
    int main() {
        while(~scanf("%d", &n)) {
            block = sqrt(n);
            for(int i=1; i<=n; i++) {
                scanf("%d", &a[i]);
                belong[i] = (i-1) / block + 1;
                b[i] = a[i];
            }
            sort(b+1, b+1+n);
            int nn = unique(b+1, b+1+n) - (b+1);
            for(int i=1; i<=n; i++) {
                a[i] = lower_bound(b+1, b+1+nn, a[i]) - b;
                v[a[i]].push_back(i);
            }
            for(int i=1; i<=belong[n]; i++)    handle(i);
            m = n;
            while(m--) {
                int l, r;
                scanf("%d%d", &l, &r);
                int ans = query(l, r);
                printf("%d
    ", b[ans]);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    hdu 1381 Crazy Search
    hdu 5131 Song Jiang's rank list
    poj 2251 Dungeon Master
    hdu 4941 Magical Forest
    hdu 1728 逃离迷宫
    hdu 2612 Find a way
    hdu 3288 Resource Allocation
    hdu 1272 小希的迷宫
    hdu 5224 Tom and paper
    hdu 5104 Primes Problem
  • 原文地址:https://www.cnblogs.com/Jiaaaaaaaqi/p/9381205.html
Copyright © 2011-2022 走看看