版权声明:转载请声明出处,谢谢支持 https://blog.csdn.net/Dreamstar_DS/article/details/83215853
DAY - 20
——远方的冲锋号角音游天际
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2724
OR https://darkbzoj.cf/problem/2724
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;
}