可以离线,子树查询,数据范围是1e5。
全局维护num[i]表示颜色i出现的次数,cnt[i]表示出现次数大于等于i次的颜色种类数。
由于num[i]每次都是加1,减1,变化是连续的,所以cnt数组的维护只需要单点修改:
当新加入颜色x,num[x]+1这个数增加1个,num[x]这个数减少1个,
所以cnt[num[x]+1]+1
,而cnt[num[x]]
不变。
同理,当减去颜色x,cnt[num[x]]-1
。
代码略。
如果考虑用树上启发式,我们同样维护num[i],cnt[i],含义一样。
当然如果用cnt[i]表示出现次数恰好等于i次的颜色种类数,那么每次查询都是区间查询,需要对cnt这个桶,建线段树维护。
#include<bits/stdc++.h>
using namespace std;
//#pragma GCC optimize(2)
#define ull unsigned long long
#define ll long long
#define pii pair<int, int>
#define pdd pair<double, double>
#define re register
#define lc rt<<1
#define rc rt<<1|1
const int maxn = 1e5 + 10;
const ll mod = 998244353;
const ll inf = (ll)4e17+5;
const int INF = 1e9 + 7;
const double pi = acos(-1.0