LOJ-6285-数列分块入门9

链接:

https://loj.ac/problem/6285

题意:

给出一个长为 的数列,以及 个操作,操作涉及询问区间的最小众数。

思路:

vector维护每个值的出现位置, 预处理第i快到第j块 的众数,然后对不成块的跑暴力,
数组开小了一直wa..找题解,好多题解代码也过不了...

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
//#include <memory.h>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <math.h>
#include <stack>
#include <string>
#include <assert.h>
#include <iomanip>
#define MINF 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int MAXN = 1e5+10;
const int MOD = 10007;

int a[MAXN], b[MAXN], Tag[MAXN];
int Num[MAXN];
int Dp[2010][2010];
int Belong[MAXN];
bool Vis[MAXN];
vector<int> Number[MAXN];
int n, part, pos;

inline int read()
{
    int ret = 0, c, f = 1;
    for(c = getchar(); !(isdigit(c) || c == '-'); c = getchar());
    if(c == '-') f = -1, c = getchar();
    for(; isdigit(c); c = getchar()) ret = ret * 10 + c - '0';
    if(f < 0) ret = -ret;
    return ret;
}

void Init(int x)
{
    int MaxNum = 0;
    int Mode = 0;
    memset(Num, 0, sizeof(Num));
    for (int i = (x-1)*part+1;i <= n;i++)
    {
        int p = Belong[i];
        Num[a[i]]++;
        if (Num[a[i]] > MaxNum)
        {
            MaxNum = Num[a[i]];
            Mode = a[i];
        }
        if (Num[a[i]] == MaxNum && Mode > a[i])
            Mode = a[i];
        Dp[x][p] = Mode;
    }
}

int GetCnt(int l, int r, int v)
{
//    int lp = lower_bound(Number[v].begin(), Number[v].end(), l)-Number[v].begin();
//    int rp = upper_bound(Number[v].begin(), Number[v].end(), r)-Number[v].begin();
//    return rp-lp+1;
    vector<int>::iterator x = upper_bound(Number[v].begin(), Number[v].end(), r);
    vector<int>::iterator y = lower_bound(Number[v].begin(), Number[v].end(), l);
    return x - y ;
}

int Query(int l, int r)
{
    int mode = Dp[Belong[l]+1][Belong[r]-1];
    int MaxNum = GetCnt(l, r, mode);
    memset(Vis, 0, sizeof(Vis));
    Vis[mode] = 1;
    for (int i = l;i <= min(Belong[l]*part, r);i++)
    {
        if (Vis[a[i]])
            continue;
        Vis[a[i]] = 1;
        int cnt = GetCnt(l, r, a[i]);
        if (cnt > MaxNum || (MaxNum == cnt && a[i] < mode))
        {
            MaxNum = cnt;
            mode = a[i];
        }
    }
    if (Belong[l] != Belong[r])
    {
        for (int i = max((Belong[r]-1)*part+1, l);i <= r;i++)
        {
            if (Vis[a[i]])
                continue;
            Vis[a[i]] = 1;
            int cnt = GetCnt(l, r, a[i]);
            if (cnt > MaxNum || (MaxNum == cnt && a[i] < mode))
            {
                MaxNum = cnt;
                mode = a[i];
            }
        }
    }
    return mode;
}

int main()
{
//    scanf("%d", &n);
    n = read();
    part = 80;
    memset(Tag, -1, sizeof(Tag));
    for (int i = 1;i <= n;i++)
    {
//        scanf("%d", &a[i]);
        a[i] = read();
        b[i] = a[i];
        Belong[i] = (i-1)/part+1;
    }
    sort(b+1, b+1+n);
    pos = unique(b+1, b+1+n)-(b+1);
    for (int i = 1;i <= n;i++)
        a[i] = lower_bound(b+1, b+1+pos, a[i])-b;

    for (int i = 1;i <= Belong[n];i++)
        Init(i);
    for (int i = 1;i <= n;i++)
        Number[a[i]].push_back(i);
    int op, l, r, c;
    for (int i = 1;i <= n;i++)
    {
//        scanf("%d%d", &l, &r);
        l = read(), r = read();
        printf("%d\n", b[Query(l, r)]);
    }

    return 0;
}
posted @ 2019-08-30 14:19  YDDDD  阅读(167)  评论(0编辑  收藏  举报