分块求调,好人一生平安!

P4168 [Violet] 蒲公英

LiuTianyou @ 2022-11-26 21:02:36

#include <bits/stdc++.h>
using namespace std;
int a[40005], c[40005], arr[40005];
vector<int> appears[40005];
pair<int, int> f[40][40];
pair<int, int> getTogether(int l, int r){
    int key, max_value = INT_MIN;
    map<int, int> hashTable;
    for(int i = l; i <= r; i++)
        hashTable[arr[i]]++;
    for(map<int, int>::iterator it = hashTable.begin(); it != hashTable.end(); it++){
        if(max_value < it->second){
            key = it->first;
            max_value = it->second;
        }
    }
    return make_pair(key, max_value);
}
int my_binary_search(vector<int>& vec, int start, int end, int value){
    int left = start, right = end;
    while(left <= right){
        int mid = (left + right) / 2;
        if(vec[mid] <= value) left = mid + 1;
        else right = mid - 1;
    }
    return right;
}
int getAppear(int l, int r, int x){
    int first_ge = lower_bound(appears[x].begin(), appears[x].end(), l) - appears[x].begin();
    int last_le = my_binary_search(appears[x], 0, appears[x].size() - 1, r);
    return last_le - first_ge + 1;
}
int main(){
    int n, m, x = 0;
    scanf("%d %d", &n, &m);
    int len = sqrt(n * log2(n));
    for(int i = 1; i <= n; i++)
        scanf("%d", &a[i]), c[i] = a[i];
    sort(c + 1, c + n + 1);
    int tot = unique(c + 1, c + n + 1) - c;
    for(int i = 1; i <= n; i++){
        arr[i] = lower_bound(c + 1, c + tot, a[i]) - c;
        appears[arr[i]].push_back(i);
    }
    printf("%d\n", len);
    for(int i = 0; i < ceil(n / (double)len); i++){
        for(int j = i; j < ceil(n / (double)len); j++){
            auto res = getTogether(i * len + 1, min((j + 1) * len, n));
            f[i][j] = res;
        }
    }
    while(m--){
        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);
        int Ll = ((l - 1) / len) * len + 1;
        int Lr = ((r - 1) / len) * len + 1;
        int p = Ll / len, q = Lr / len;
        int ans = 0, max_appear = INT_MIN;
        if(p == q){
            ans = f[p][q].first;
            max_appear = f[p][q].second;
        }else{
            for(int i = l; i <= Ll + len - 1; i++){
                int appear = getAppear(l, r, arr[i]);
                printf("%d in [%d, %d] appears %d times.\n", arr[i], l, r, appear);
                if(max_appear < appear){
                    ans = arr[i];
                    max_appear = appear;
                }
            }
            if(max_appear < f[p + 1][q - 1].second){
                ans = f[p + 1][q - 1].first;
                max_appear = f[p + 1][q - 1].second;
            }
            for(int i = Lr; i <= r; i++){
                int appear = getAppear(l, r, arr[i]);
                if(max_appear < appear){
                    ans = arr[i];
                    max_appear = appear;
                }
            }
        }
        x = c[ans];
        printf("%d\n", x);
    }
    return 0;
}

小样例测试一点事没有


by LiuTianyou @ 2022-11-26 21:02:50

@凤年


|