1. 程式人生 > >BZOJ2724. [Violet 6]蒲公英(分塊)

BZOJ2724. [Violet 6]蒲公英(分塊)

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; }