Manioc

SQRTT

May 6th, 2019
238
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.23 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define MAX 100007
  3. #define SQ 327
  4. #define  mp make_pair
  5.  
  6. using namespace std;
  7. typedef long long ll;
  8. typedef pair<int, int> pii;
  9.  
  10. int bucket[MAX], freq[SQ][MAX];
  11. pii interval[SQ][SQ];
  12. int ini[MAX], fim[MAX], a[MAX], n;
  13.  
  14. int actual[MAX];
  15. struct SQRTT {
  16.  
  17.     void build(){
  18.         memset(ini, -1, sizeof ini);
  19.         memset(fim, -1, sizeof fim);
  20.         // Delimitando intervalos dos buckets
  21.         bucket[0] = 0; ini[0] = 0;
  22.         for(int i = 1; i < n; i++){
  23.             bucket[i] = i/SQ;
  24.             ini[bucket[i]] = (bucket[i] != bucket[i-1])? i: ini[bucket[i]];
  25.             fim[bucket[i-1]] = (bucket[i] != bucket[i-1])? i-1: fim[bucket[i-1]];
  26.         }
  27.         fim[bucket[n-1]] = n-1;
  28.  
  29.         // Acumulando
  30.         for(int i = 0; i < n; i++) freq[bucket[i]][a[i]]++;
  31.  
  32.         for(int i = 1; i < SQ && ini[i] != -1; i++){
  33.             for(int j = 0; j < n; j++) freq[i][j] += freq[i-1][j];
  34.         }
  35.  
  36.         // pegando a melhor resposta entre os buckets
  37.         for(int i = 0; i < SQ && ini[i] != -1; i++){
  38.             memset(actual, 0, sizeof actual);
  39.             int best = a[ini[i]];
  40.             for(int j = ini[i]; j < n; j++){
  41.                 actual[a[j]]++;
  42.                 if(actual[a[j]] > actual[best]) best = a[j];
  43.  
  44.                 if(fim[bucket[j]] == j) {interval[i][bucket[j]].first = best; interval[i][bucket[j]].second = actual[best];}
  45.             }
  46.         }
  47.         memset(actual, 0, sizeof actual);
  48.     }
  49.  
  50.     int query(int l, int r){
  51.         int bl = bucket[l], br = bucket[r];
  52.         if(bl == br){
  53.             int best = l;
  54.             for(int i = l; i <= r; i++){
  55.                 actual[a[i]]++;
  56.                 if(actual[a[i]] > actual[best]) best = a[i];
  57.             }
  58.  
  59.             // limpando
  60.             for(int i = l; i <= r; i++) actual[a[i]]--;
  61.             return best;
  62.         }
  63.  
  64.         bl++; br--;
  65.         pii best;
  66.         if(bl <= br) best = interval[bl][br];
  67.         else best = mp(-1, -1);
  68.         bl--; br++;
  69.  
  70.         for(int i = l; i <= fim[bl]; i++) actual[a[i]]++;
  71.         for(int i = ini[br]; i <= r; i++) actual[a[i]]++;
  72.  
  73.         for(int i = l; i <= fim[bl]; i++) {
  74.             int total = freq[br-1][a[i]];
  75.             total -= freq[bl][a[i]];
  76.  
  77.             total = (total < 0)? actual[a[i]]: total + actual[a[i]];
  78.             best.first = (total > best.second)? a[i]: best.first;
  79.             best.second = (total > best.second)? total: best.second;
  80.         }
  81.         for(int i = ini[br]; i <= r; i++) {
  82.             int total = freq[br-1][a[i]];
  83.             total -= freq[bl][a[i]];
  84.  
  85.             total = (total < 0)? actual[a[i]]: total + actual[a[i]];
  86.             best.first = (total > best.second)? a[i]: best.first;
  87.             best.second = (total > best.second)? total: best.second;
  88.         }
  89.  
  90.         // limpando
  91.         for(int i = l; i <= fim[bl]; i++) actual[a[i]]--;
  92.         for(int i = ini[br]; i <= r; i++) actual[a[i]]--;
  93.         return best.first;
  94.     }
  95. };
  96.  
  97. int main(){
  98.     SQRTT ds;
  99.     int m; scanf("%d %d", &n, &m);
  100.  
  101.     for(int i = 0; i < n; i++) scanf("%d", &a[i]);
  102.  
  103.     ds.build();
  104.     while((m--)){
  105.         int l, r; scanf("%d %d", &l, &r);
  106.         printf("%d\n", ds.query(l, r));
  107.     }
  108.    
  109.     return 0;
  110. }
Advertisement
Add Comment
Please, Sign In to add comment