luogu P3709大爷的字符串题

lxl出的又一道毒瘤题,题目本身让人读不懂,然而实际上题面用一句话就可以总结:

给你n个数,m次询问区间[l,r]中众数的出现次数

然后就用普通的莫队就好啦~~(数据也没有那么毒瘤)

#include<algorithm>
#include<cmath>
#include<cstdio>
using namespace std;
const int maxn = 200200;
int pos[maxn], num[maxn];
int ans[maxn];
int flag[maxn];
int a[maxn], A[maxn];
int n, m, block;
int L = 0, R = 0;
int Ans = 0;
struct node{
    int l, r ,id;
    inline bool operator < (const node &x) const {
    return l / block == x.l / block ? r < x.r : l / block < x.l / block; 
  }
}Q[maxn];

inline void add(int x)
{
    num[flag[a[x]]]--;
    num[++flag[a[x]]]++;
    Ans = max(Ans,flag[a[x]]);
}
inline void del(int x)
{
    if(flag[a[x]] ==Ans && num[flag[a[x]]] == 1)
    Ans--;
    num[flag[a[x]]]--;
    num[--flag[a[x]]]++;
}
int main()
{
    scanf("%d %d", &n, &m);
    block = sqrt(m);
    int N = n;
    for(int i = 1;i <= n;i++)
    {
        scanf("%d", &a[i]);
        A[i] = a[i];
    }
    sort(A + 1,A + n + 1);
    n = unique(A + 1,A + n + 1) - A - 1;
    for(int i = 1;i <= N;i++)
    a[i] = lower_bound(A + 1,A + n + 1,a[i]) - A;
    for(int i = 1;i <= m;i++)
    {
        scanf("%d %d", &Q[i].l, &Q[i].r);
        Q[i].id = i;
    }
    sort(Q + 1, Q + 1 + m);
    for(int i = 1;i <= m;i++)
    {
        while(L < Q[i].l) del(L++);
        while(L > Q[i].l) add(--L);
        while(R < Q[i].r) add(++R);
        while(R > Q[i].r) del(R--);
        ans[Q[i].id] = -Ans;
    }
    for(int i = 1;i <= m;i++)
    printf("%d\n", ans[i]);
    return 0;
}

我竟然因为在原先模版中的flag[0] = 1;没有删去只得了20分QAQ。

posted @ 2019-03-30 17:55  机器闵  阅读(108)  评论(0编辑  收藏  举报