BZOJ2120

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2120

#include <bits/stdc++.h>

using namespace std;
const int N = 10007;
int n, c[N], sum[N*100], ans[N], belong[N], BLOCK, res = 0; //ans答案数组,totq总询问,totch总修改,res当前答案.sum[c[i]]当前颜色总数
struct node1
{
    int l, r, cnt, id;
    bool operator < (const node1 &x) const {
        return belong[l] < belong[x.l] || (belong[l]==belong[x.l] && belong[r] < belong[x.r]) || (belong[l]==belong[x.l] && belong[r] == belong[x.r] && cnt < x.cnt);
    }
}Q[N];
struct node2
{
    int x, y;
}C[N];
void add(int p)
{
    sum[c[p]] ++;
    if(sum[c[p]] == 1) res ++;
}
void dec(int p)
{
    sum[c[p]] --;
    if(sum[c[p]] == 0) res --;
}
void update(int now, int i)
{
    if(C[now].x >= Q[i].l && C[now].x <= Q[i].r) {
        if(--sum[c[C[now].x]] == 0) res --;
        if(++sum[C[now].y] == 1) res ++;
    }
    swap(c[C[now].x], C[now].y); //重点
}
int main()
{
    char opt[3];
    int totq = 0, totch = 0, q;
    scanf("%d%d",&n,&q);  BLOCK = sqrt(n);
    for(int i = 1; i <= n; i ++)  scanf("%d",&c[i]);
    for(int i = 1; i <= n; i ++) belong[i] = (i - 1) / BLOCK + 1;
    for(int i = 1; i <= q; i ++) {
        int x, y;
        scanf("%s%d%d",opt,&x,&y);
        if(opt[0] == 'Q') {
            totq ++;
            Q[totq].l = x, Q[totq].r = y, Q[totq].id = totq, Q[totq].cnt = totch;
        } else {
            totch ++;
            C[totch].x = x, C[totch].y = y;
        }
    }
    sort(Q+1, Q+1+totq);
    for(int i = 1, l = 1, r = 0, now = 0;i <= totq;i ++) {
        while(Q[i].r > r) add(++r);
        while(Q[i].r < r) dec(r--);
        while(Q[i].l > l) dec(l++);
        while(Q[i].l < l) add(--l);
        while(Q[i].cnt > now) update(now + 1, i), now ++;
        while(Q[i].cnt < now) update(now, i), now --;
        ans[Q[i].id] = res;
    }
    for(int i = 1; i <= totq; i ++) printf("%d\n", ans[i]);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值