题目
题解
由打表得对于任意\(i \geq 1\),都有第\(i+1\)行和第\(i+3\)行相等、
于是我们可以分块维护一下。
然后做完了。
代码
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>using namespace std;const int N = 100010, M = 10010;const int block = 1250;int Cnt[2][85][M];
int belong[N], siz;
int pl[85], pr[85];int a[N];void build(int n)
{for (int i = 1; i <= n; i++) belong[i] = (i-1) / block + 1;for (int i = 1; i <= n; i++)if (!pl[belong[i]]) pl[belong[i]] = i;if (!pl[belong[i]]) pl[belong[i]] = i;for (int i = n; i >= 1; i--)if (!pr[belong[i]]) pr[belong[i]] = i;siz = belong[n];for (int i = 1; i <= siz; i++)for (int j = 1; j <= pr[i]; j++) Cnt[0][i][a[j]]++;static int sum[N];memset(sum, 0, sizeof(sum));for (int i = 1; i <= siz; i++){for (int j = 1; j <= pr[i]; j++)sum[a[j]]++, Cnt[1][i][sum[a[j]]]++;for (int j = 1; j <= pr[i]; j++)sum[a[j]]--;}
}void upd(int v, int id)
{for (int i = belong[id]; i <= siz; i++){Cnt[1][i][ Cnt[0][i][a[id]] ]--;Cnt[0][i][a[id]]--;Cnt[0][i][v]++;Cnt[1][i][ Cnt[0][i][v] ]++;}a[id] = v;
}inline int qry(int x, int y)
{if (x == 1) return a[y];int sum = Cnt[0][belong[y]-1][a[y]];for (int i = pl[belong[y]]; i <= y; i++)if (a[i] == a[y]) sum++;if (!(x & 1)) return sum;int Ans = Cnt[1][belong[y]-1][sum];for (int i = pl[belong[y]]; i <= y; i++)Cnt[0][belong[y]-1][a[i]]++,Ans += (Cnt[0][belong[y]-1][a[i]] == sum);for (int i = pl[belong[y]]; i <= y; i++)Cnt[0][belong[y]-1][a[i]]--;return Ans;
}int main()
{int n;scanf("%d", &n);for (int i = 1; i <= n; i++)scanf("%d", &a[i]);build(n);int m;scanf("%d", &m);while (m--){int opt;scanf("%d", &opt);if (opt == 1){int v, i;scanf("%d %d", &v, &i);upd(v, i);}else{int x, y;scanf("%d %d", &x, &y);printf("%d\n", qry(x, y));}}return 0;
}