【诸位大佬,救救孩子!】

P4168 [Violet] 蒲公英

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

听说暴力卡常满分


|