题目分析:
首先给出一段序列,共 m 次询问,每一次询问求出给定区间内出现正偶数次数的个数。
算法讲解:
首先,如果忽略本题强制在线的话,可以用莫队来做。
但是,题目中已经规定了需要强制在线来做,于是只能另求他法。
看到数据范围,再结合一下题意,这道题可以用分块来做。
首先,定义两个数组cnt[i][j]表示前i块中j出现的次数ans[i][j]表示第i到第j个块中,出现偶数次数的个数。
这两个数组需要先预处理出来,先来看cnt数组。
相当于一个前缀和的思想,先输入把每一个数+1,然后依次枚举块,把前一块中这个数的出现次数加起来。
for(re int i(1) ; i<=n ; ++i){
a[i] = read();
pos[i] = (i-1)/blocksize+1;
cnt[pos[i]][a[i]]++;
}
for(re int i(1) ; i<=tot ; ++i){
for(re int j(0) ; j<=c ; ++j){
cnt[i][j] += cnt[i-1][j];
}
}
然后来看ans数组。
先枚举每一个块,枚举右端点,让ans[i][j]=ans[i][j−1]作为初始值,往后枚举块j的右端点,可以用一个桶来记录出现次数,具体看代码。
for(re int i(1) ; i<=tot ; ++i){
for(re int j(i) ; j<=tot ; ++j){
ans[i][j] = ans[i][j-1]; //赋值
for(re int k(l[j]) ; k<=r[j] ; +