BZOJ2724. [Violet 6]蒲公英(分塊)
阿新 • • 發佈:2018-12-16
8個小時的鬥智鬥勇… 我也不知道為什麼這道題成了我目前所有學科中用時最長的一道題 聽說此題可以各種暴力卡過233 其實就是一個很簡單的預處理,由於分塊思想(即只暴力處理角塊)我們就可以預處理出整塊之間的眾數(nsqrt(n)),然後對於每個區間我們就需要處理角塊即可~(暴力取最優) 本題需要一個簡單的離散化(甚至你不需要排序) 本題塊大小取sqrt(n / log2(n))最優(我也不知道為什麼,當然你sqrt(n)也是可以過的) AC Code:
#include<bits/stdc++.h>
#define rg register
#define maxn 200005
#define il inline
#define ll long long
using namespace std;
il int read(){rg int x = 0 , w = 1;rg char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-') w = -1;ch = getchar();}while (ch >= '0' && ch <= '9'){x = (x<<3) + (x<<1) + ch - '0';ch = getchar();}return x * w;}
int a[maxn] , b[maxn] , belong[maxn] , sum[maxn];
int num , sum2[maxn] , tot , q[maxn] , cnt[50002] , f[1000][1000];
int totn , val[maxn] , block;
vector <int> v[50005];
map<int , int>mp;
void init(int n){
block = sqrt(n / log2(n));
for (rg int i = 1 ; i <= n ; ++i)
belong[i] = (i - 1) / block + 1;
}
void pre(int n){
for (rg int i = 1 ; i <= belong[n] ; ++i){
memset(cnt , 0 , sizeof(cnt));
rg int ans = 0 , mx = 0;
for (rg int j = (i - 1) * block + 1; j <= n ; ++j){
++cnt[a[j]];
if (cnt[a[j]] > mx || (cnt[a[j]] == mx && val[a[j]] < val[ans]))
ans = a[j] , mx = cnt[a[j]];
f[i][belong[j]] = ans;
}
}
}
int find(int l0 , int r0 , int x){
rg int t = upper_bound(v[x].begin() , v[x].end() , r0) - lower_bound(v[x].begin() , v[x].end() , l0);
return t;
}
int query(int l0 , int r0){
rg int ans = f[belong[l0] + 1][belong[r0] - 1] , mx = find(l0 , r0 , ans);
rg int tmp;
rg int minr = min(r0 , belong[l0] * block);
for (rg int i = l0 ; i <= minr ; ++i){
tmp = find(l0 , r0 , a[i]);
if (tmp > mx || (tmp == mx && val[a[i]] < val[ans]))
mx = tmp , ans = a[i];
}
if (belong[l0] != belong[r0])
for (rg int i = (belong[r0] - 1) * block + 1 ; i <= r0 ; ++i){
tmp = find(l0 , r0 , a[i]);
if (tmp > mx || (tmp == mx && val[a[i]] < val[ans]))
mx = tmp , ans = a[i];
}
return ans;
}
int main(){
rg int n = read() , m = read() , x , c;
for (rg int i = 1 ; i <= n ; ++i){
a[i] = b[i] = read();
}
sort(b + 1 , b + 1 + n);
tot = unique(b + 1 , b + 1 + n) - (b + 1);
for (rg int i = 1 ; i <= n ; ++i){
rg int x = a[i];
a[i] = lower_bound(b + 1 , b + 1 + n , x) - b;
val[a[i]] = x;
v[a[i]].push_back(i);
}
init(n);
pre(n);
int l0 , r0 , ans = 0;
memset(sum , 0 , sizeof(sum));
for (rg int i = 1 ; i <= m ; ++i){
l0 = (read() + ans - 1) % n + 1 , r0 = (read() + ans - 1) % n + 1;
if (l0 > r0)
swap(l0 , r0);
printf("%d\n" , ans = val[query(l0 , r0)]);
}
return 0;
}