单点修改莫队 UVA

单点修改莫队 UVA - 12345【Dynamic len(set(a[L:R]))】

https://cn.vjudge.net/contest/304248#problem/L

题意

给定 n 个数和 m 次操作,数组下标 [0, n-1] ,操作分为两种:

  • Q x y —— 查询区间 [x, y] 内出现过几个值
  • M x y —— 将 a[x] 修改成 y

分析

手贱全删没了...不想写了,下一篇里都差不多的...

代码

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <vector>
#include <string>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <numeric>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

const int maxn = 1e6+5;

int n, m;
int a[maxn];
int new_a[maxn];
int block;
int cnt, cnt_;
int ans[maxn];
int mark[maxn];
int sum[maxn];
int res;

struct node{
    int l, r, id, t;
    bool operator < (const node &a) const {
        if(l/block == a.l/block && r/block == a.r/block) {
            return t < a.t;
        }
        if(l/block == a.l/block) {
            return r < a.r;
        }
        return l < a.l;
    }
}Q[maxn];

struct Change {
    int x, now, cur;
}C[maxn];

void init() {
    block = (int)pow(n, 2.0/3);
    memset(mark, 0, sizeof(mark));
    memset(sum, 0, sizeof(sum));
    cnt = cnt_ = 0;
    res = 0;
}

void update(int x) {
    if(mark[x]) {
        if(sum[a[x]] == 1) {
            res --;
        }
        sum[a[x]]--;
    }
    else {
        if(sum[a[x]] == 0) {
            res ++;
        }
        sum[a[x]] ++;
    }
    mark[x] ^= 1;
}

void change_time(int x, int val) {
    if(mark[x]) {
        update(x);
        a[x] = val;
        update(x);
    }
    else {
        a[x] = val;
    }
}

int main() {
    // fopen("in.txt", "r", stdin);
    // fopen("out.txt", "w", stdout);
    while(~scanf("%d%d", &n, &m)) {
        init();
        for(int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            new_a[i] = a[i];
        }
        for(int i = 1; i <= m; i++) {
            char f[10];
            int x, y;
            scanf("%s%d%d", f, &x, &y);
            x = x + 1;
            if(f[0] == 'Q') {
                Q[++cnt].l = x;
                Q[cnt].r = y;
                Q[cnt].id = cnt;
                Q[cnt].t = cnt_;
            }
            else {
                C[++cnt_].x = x;
                C[cnt_].now = y;
                C[cnt_].cur = new_a[x];
                new_a[x] = y;
            }
        }
        sort(Q+1, Q+1+cnt);
        int l = 1, r = 0;
        int Time = 0;
        for(int i = 1; i <= cnt; i++) {
            while(l < Q[i].l) {
                update(l);
                l++;
            }
            while(l > Q[i].l) {
                l--;
                update(l);
            }
            while(r < Q[i].r) {
                r++;
                update(r);
            }
            while(r > Q[i].r) {
                update(r);
                r--;
            }
            while(Time < Q[i].t) {
                Time++;
                change_time(C[Time].x, C[Time].now);
            }
            while(Time > Q[i].t) {
                change_time(C[Time].x, C[Time].cur);
                Time--;
            }
            ans[Q[i].id] = res;
        }
        for(int i = 1; i <= cnt; i++) {
            printf("%d
", ans[i]);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Decray/p/10947035.html