TangLongbin @ 2019-02-09 17:45:03
分块做的,g[i][j]表示前i个块(包括第i块)中j出现的次数,f[i][j]表示第i至j块中众数出现的位置(最后一个位置,也就是记录众数);
调了一下午,只有10分,希望诸位大佬帮忙看看是什么问题;
请看代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define Max 40010
#define Maxs 250
using namespace std;
int n,m,ans;
int L,R;
int id[Max],belong[Max];
int f[Maxs][Maxs],g[Maxs][Max],sum[Max];
struct node{
int v,p;
}a[Max];
int read(){
char c = getchar();int res = 0, f = 1;
while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();}
while('0' <= c && c <= '9'){res = (res<<3) + (res<<1) + c - '0';c = getchar();}
return f * res;
}
bool cmp(const node &x,const node &y){return x.v < y.v;}
bool back(const node &x,const node &y){return x.p < y.p;}
void init(){
n = read(); m = read();
for(register int i = 1 ; i <= n ; ++i)a[i].v = read(),a[i].p = i;
sort(a+1,a+1+n,cmp);
for(register int i = 1 ; i <= n ; ++i){
if(a[i].v != a[i-1].v)id[a[i].p] = ++id[0];
else id[a[i].p] = id[a[i-1].p];
}
sort(a+1,a+1+n,back);
int x = sqrt(n);
for(register int i = 1 ; i <= n ; ++i)belong[i] = (i-1)/x+1;
int blo = belong[n];
for(register int i = 1 ; i <= blo ; ++i){
for(register int j = (i-1)*x+1 ; j <= min(n,i*x) ; ++j)g[i][id[j]]++;
for(register int j = 1 ; j <= id[0] ; ++j)g[i][j] += g[i-1][j];
}
id[0] = 0;
for(register int i = 1 ; i <= blo ; ++i){
for(register int j = i ; j <= blo ; ++j){
ans = 0;
for(register int k = (j-1)*x+1 ; k <= min(n,j*x) ; ++k){
int A = g[j][id[k]] - g[i-1][id[k]];
int B = g[j][id[ans]] - g[i-1][id[ans]];
if(A > B ||(A == B && id[ans] > id[k]))ans = k;
}
f[i][j] = ans;
}
}
}
int cnt(){
memset(sum,0,sizeof(sum)); ans = 0;
if(belong[L] == belong[R]||belong[L] + 1 == belong[R]){
for(register int i = L ; i <= R ; ++i){
sum[id[i]]++;
int A = sum[id[i]];
int B = sum[id[ans]];
if(A > B || (A == B && id[i] < id[ans]))ans = i;
}
}
else{
int pre = belong[L] + 1 , next = belong[R] - 1 , x = sqrt(n);
ans = f[pre][next];
for(register int i = L ; i <= belong[L] * x ; ++i){
sum[id[i]]++;
int A = sum[id[i]] + g[next][id[i]] - g[pre-1][id[i]];
int B = sum[id[ans]] + g[next][id[ans]] - g[pre-1][id[ans]];
if(A > B || (A == B && id[i] < id[ans])) ans = i;
}
for(register int i = next * x + 1 ; i <= R ; ++i){
sum[id[i]]++;
int A = sum[id[i]] + g[next][id[i]] - g[pre-1][id[i]];
int B = sum[id[ans]] + g[next][id[ans]] - g[pre-1][id[ans]];
if(A > B || (A == B && id[i] < id[ans])) ans = i;
}
}
return a[ans].v;
}
void solve(){
int l,r;ans = 0;
while(m--){
l = read(); r = read();
L = (l + a[ans].v - 1) % n + 1; R = (r + a[ans].v - 1) % n + 1;
if(L > R)swap(L,R);
printf("%d\n",cnt());
}
}
int main(){
init();
solve();
return 0;
}
by hyfhaha @ 2019-02-09 18:10:54
听说暴力卡常满分