莫隊 (codeforces-220B Little Elephant and Array)

題目鏈接
入門級的莫隊,網上的題解都是結合離散化,在我看了其實是畫蛇添足。因爲當一個x是大於1e5時,他是不可能構成出現x次的(因爲n<=1e5),這個咱們只要return掉,不用管就行了。這裏保險起見開得1e6。我們定義g[i]g[i]爲i出現的個數。
比較容易使用莫隊轉移狀態。
下面是ac代碼:

#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <map>
#define ll long long
using namespace std;
const int N = 1e5+5;
ll c[N];
ll sum[N];
map<int, int> mp;
struct Node
{
    ll l, r, id;
}q[N];
ll anss[N];
ll block;
ll ans = 0;
int gg[N*10];
bool cmp(Node a, Node b)
{
    return (a.r / block == b.r /block) ? a.l < b.l:a.r < b.r;
}
void del (int x)
{
    if (c[x] > 1e6) return;
    gg[c[x]]--;
    if (gg[c[x]] == c[x]) ans++;
    else if (gg[c[x]] == c[x]-1) ans--;
}
void add(int x)
{
    if (c[x] > 1e6) return;
    gg[c[x]]++;
    if (gg[c[x]] == c[x]) ans++;
    else if (gg[c[x]] == c[x]+1) ans--;
}
int main()
{
    ll n, m, k;
    scanf("%lld%lld", &n, &m);
    block = sqrt(n);
    for (int i = 1; i <= n; i++)
        scanf("%lld", &c[i]);
    for (int i = 1; i <= m; i++)
    {
        scanf("%lld%lld", &q[i].l, &q[i].r);
        q[i].id = i;
    }
    sort(q+1, q+m+1, cmp);
    int l = 1, r = 0;
    for (int i = 1; i <= m; i++)
    {
        ll ql = q[i].l, qr = q[i].r;
        while(l < ql) del(l++);
        while(l > ql) add(--l);
        while(r < qr) add(++r);
        while(r > qr) del(r--);
        anss[q[i].id] = ans;
    }
    for (int i = 1; i <= m; i++)
        printf("%lld\n", anss[i]);
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章