bzoj 2120: 数颜色

莫队水过

每次修改之间的询问用莫队搞一下,还挺快……

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
using namespace std;
#define MAXN 100003
#define MAXQ 100003
int n, a[MAXN], sqrtn;
struct Qtype
{
    int num;
    char opt;
    int x, y;
} qy[MAXQ];
bool cmp(const Qtype &a, const Qtype &b)
{
    int ax = a.x / sqrtn, bx = b.x / sqrtn;
    if (ax != bx)
        return ax < bx;
    return a.y < b.y;
}
map<int, int> lisan;
int lct = 0;
int ct[MAXN], ans[MAXN];
void work(int ql, int qr)
{
    int l, r, m;
    l = r = m = 0;
    memset(ct, 0, sizeof(ct));
    for (int i = ql; i < qr; ++i)
        qy[i].num = i - ql;
    sort(qy + ql, qy + qr, cmp);
    for (int i = ql; i < qr; ++i)
    {
        while (l < qy[i].x)
        {
            if (--ct[a[l]] == 0)
                --m;
            ++l;
        }
        while (l > qy[i].x)
        {
            --l;
            if (++ct[a[l]] == 1)
                ++m;
        }
        while (r < qy[i].y)
        {
            if (++ct[a[r]] == 1)
                ++m;
            ++r;
        }
        while (r > qy[i].y)
        {
            --r;
            if (--ct[a[r]] == 0)
                --m;
        }
        ans[qy[i].num] = m;
    }
    for (int i = ql; i < qr; ++i)
        printf("%d\n", ans[i - ql]);
}
int main()
{
    int Q;
    scanf("%d%d", &n, &Q);
    sqrtn = sqrt(n);
    for (int i = 0; i < n; ++i)
        scanf("%d", &a[i]);
    for (int i = 0; i < Q; ++i)
    {
        scanf(" %c%d%d", &qy[i].opt, &qy[i].x, &qy[i].y);
        --qy[i].x;
    }
    for (int i = 0; i < n; ++i)
    {
        map<int, int>::iterator it = lisan.find(a[i]);
        if (it == lisan.end())
        {
            lisan[a[i]] = lct;
            a[i] = lct++;
        }
        else
            a[i] = it->second;
    }
    for (int i = 0; i < Q; ++i)
        if (qy[i].opt == 'R')
        {
            map<int, int>::iterator it = lisan.find(qy[i].y);
            if (it == lisan.end())
            {
                lisan[qy[i].y] = lct;
                qy[i].y = lct++;
            }
            else
                qy[i].y = it->second;
        }
    int last = 0;
    for (int i = 0; i <= Q; ++i)
        if (i == Q)
            work(last, i);
        else if (qy[i].opt == 'R')
        {
            work(last, i);
            a[qy[i].x] = qy[i].y;
            last = i + 1;
        }
    return 0;
}


阅读更多
文章标签: bzoj
想对作者说点什么? 我来说一句

BZOJ 2120颜色

分块

Orion_Rigel Orion_Rigel

2016-10-19 21:14:55

阅读数:151

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭