【bzoj2724】[Violet 6]蒲公英 分塊+STL-vector
阿新 • • 發佈:2017-06-23
tdi data 時間復雜度 include ole log put for output
題目描述
輸入
修正一下
l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n + 1
輸出
樣例輸入
6 3
1 2 3 2 1 2
1 5
3 6
1 5
樣例輸出
1
2
1
題解
分塊+STL-vector
一個顯而易見的結論:區間眾數一定是一段連續的塊的眾數或塊外的數,證明略(逃
先把數據離散化,然後分塊預處理出f[i][j],表示從塊i到塊j的眾數位置。具體實現的話直接開個桶存一下就好了。
然後考慮詢問,整塊的直接拿出來求一下出現次數,塊外的單獨拿出來求一下出現次數,只要求$2\sqrt n+1$次。
現在只要想出怎樣求出來出現次數即可。一個簡單地方法是:對於每個數開一個vector存一下出現位置,然後在vector上二分查找出現位置。
總時間復雜度為$O(n\sqrt n\log n)$,常數有點大...
#include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #define N 50010 #define bl(x) (x - 1) / si using namespace std; vector<int> v[N]; int a[N] , c[N] , cnt[N] , f[250][250] , ref[N]; int query(int p , int l , int r) { return upper_bound(v[p].begin() , v[p].end() , r) - lower_bound(v[p].begin() , v[p].end() , l); } int main() { int n , m , si , i , j , t , maxn , x , y , ans , last = 0; scanf("%d%d" , &n , &m) , si = (int)sqrt(n); for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &a[i]) , c[i] = a[i]; sort(c + 1 , c + n + 1); for(i = 1 ; i <= n ; i ++ ) t = a[i] , a[i] = lower_bound(c + 1 , c + n + 1 , a[i]) - c , v[a[i]].push_back(i) , ref[a[i]] = t; for(i = 0 ; i <= (n - 1) / si ; i ++ ) { memset(cnt , 0 , sizeof(cnt)) , maxn = 0; for(j = i * si + 1 ; j <= n ; j ++ ) { cnt[a[j]] ++ ; if(cnt[a[j]] > maxn || (cnt[a[j]] == maxn && a[j] < t)) maxn = cnt[a[j]] , t = a[j]; if(j % si == 0) f[i][bl(j)] = t; } } while(m -- ) { scanf("%d%d" , &x , &y) , x = (x + last - 1) % n + 1 , y = (y + last - 1) % n + 1 , maxn = 0; if(x > y) swap(x , y); if(bl(y) - bl(x) < 2) { for(i = x ; i <= y ; i ++ ) if((t = query(a[i] , x , y)) > maxn || (t == maxn && a[i] < ans)) maxn = t , ans = a[i]; } else { for(i = x ; i <= (bl(x) + 1) * si ; i ++ ) if((t = query(a[i] , x , y)) > maxn || (t == maxn && a[i] < ans)) maxn = t , ans = a[i]; if((t = query(f[bl(x) + 1][bl(y) - 1] , x , y)) > maxn || (t == maxn && f[bl(x) + 1][bl(y) - 1] < ans)) maxn = t , ans = f[bl(x) + 1][bl(y) - 1]; for(i = bl(y) * si + 1 ; i <= y ; i ++ ) if((t = query(a[i] , x , y)) > maxn || (t == maxn && a[i] < ans)) maxn = t , ans = a[i]; } printf("%d\n" , last = ref[ans]); } return 0; }
【bzoj2724】[Violet 6]蒲公英 分塊+STL-vector