danefishhh @ 2019-10-21 15:04:09
注释很清楚了..4WA 16TLE 调吐了..大佬帮忙看看
#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
int n, m, t, sum;
int a[40010], b[40010], pos[40010], L[40010], R[40010], s[210][40010], f[210][210];
vector <int > v[40010];//v[i]记录i出现的位置
void pre() {
for(int i = 1; i <= t; i ++) {
L[i] = (i - 1) * t + 1;
R[i] = i * t;
}
if(R[t] < n) t ++, L[t] = R[t - 1] + 1, R[t] = n;
for(int i = 1; i <= t; i ++) {
for(int j = L[i]; j <= R[i]; j ++) {
pos[j] = i;
}
}
for(int i = 1; i <= t; i ++) {
for(int j = L[i]; j <= R[i]; j ++) {
s[i][a[j]] ++;
}
for(int j = 1; j <= sum; j ++) {
s[i][j] += s[i - 1][j];
}
}//s[i][j]前缀和 : 前i块j出现的次数
for(int i = 1; i <= t; i ++) {
for(int j = i; j <= t; j ++) {
int id = f[i][j - 1];
int maxn = 0;
for(int k = L[j]; k <= R[j]; k ++) {
if(s[j][a[k]] - s[i - 1][a[k]] == maxn) {
if(a[k] < id) id = a[k];
}
if(s[j][a[k]] - s[i - 1][a[k]] > maxn) {
id = a[k];
maxn = s[j][a[k]] - s[i - 1][a[k]];
}
}
f[i][j] = id;
}
}//块 i ~ j 众数 f[i][j]
}
int query(int l, int r) {
int p = pos[l], q = pos[r];
int maxn = 0, id = 0;
if(p == q) {//暴力
for(int i = l; i <= r; i ++) {
int ll = lower_bound(v[a[i]].begin(), v[a[i]].end(), l) - v[a[i]].begin();//大于等于l的a[i]最先出现的位置
int rr = upper_bound(v[a[i]].begin(), v[a[i]].end(), r) - v[a[i]].begin() - 1;//小于等于r的a[i]最后出现的位置
if((rr - ll + 1) > maxn) {
maxn = rr - ll + 1;
id = a[i];
} else if((rr - ll + 1) == maxn) {
id = min(id, a[i]);
}
}
} else {
for(int i = l; i <= R[p]; i ++) {
int ll = lower_bound(v[a[i]].begin(), v[a[i]].end(), l) - v[a[i]].begin();
int rr = upper_bound(v[a[i]].begin(), v[a[i]].end(), r) - v[a[i]].begin() - 1;
if((rr - ll + 1) > maxn) {
maxn = rr - ll + 1;
id = a[i];
} else if((rr - ll + 1) == maxn) {
id = min(id, a[i]);
}
}
for(int i = L[q]; i <= r; i ++) {
int ll = lower_bound(v[a[i]].begin(), v[a[i]].end(), l) - v[a[i]].begin();
int rr = upper_bound(v[a[i]].begin(), v[a[i]].end(), r) - v[a[i]].begin() - 1;
if((rr - ll + 1) > maxn) {
maxn = rr - ll + 1;
id = a[i];
} else if((rr - ll + 1) == maxn) {
id = min(id, a[i]);
}
}
if(p + 1 <= q - 1) {//整块的
if(s[q - 1][f[p + 1][q - 1]] - s[p][f[p + 1][q - 1]] > maxn) {
id = f[p + 1][q - 1];
maxn = s[q - 1][f[p + 1][q - 1]] - s[p][f[p + 1][q - 1]];
} else if(s[q - 1][f[p + 1][q - 1]] - s[p][f[p + 1][q - 1]] == maxn) {
id = min(id, f[p + 1][q - 1]);
}
}
}
return id;
}
int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i ++) {
scanf("%d", &a[i]);
b[i] = a[i];
}
std::sort(b + 1, b + n + 1);
sum = std::unique(b + 1, b + n + 1) - b - 1;//sum为种类数
for(int i = 1; i <= n; i ++) {
a[i] = lower_bound(b + 1, b + sum + 1, a[i]) - b;
v[a[i]].push_back(i);
}
for(int i = 1; i <= sum; i ++) v[i].push_back(INF);//加一个最大值方便二分
for(int i = 1; i <= sum; i ++) sort(v[i].begin(), v[i].end());
t = sqrt(n);
pre();
int x = 0;
for(int i = 1; i <= m; i ++) {
int l, r;
scanf("%d%d", &l, &r);
l = (l + x - 1) % n + 1, r = (r + x - 1) % n + 1;
if(l > r) swap(l, r);
printf("%d\n", x = query(l, r));
}
return 0;
}
by danefishhh @ 2019-10-21 15:07:04
那个 vector 的排序是没用的..它们本来就是有序的