Manioc

seg sqrt

Aug 10th, 2018
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.40 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define MAX 10000007
  3.  
  4. using namespace std;
  5.  
  6. int raiz, n;
  7. vector<int> block;
  8. vector<vector<int> > arr;
  9. int val[MAX];
  10.  
  11. void print(){
  12.     for(int i = 0; i < arr.size(); i++){
  13.         cout << "Raiz " << (i+1) << " = ";
  14.         for(int j = 0; j < arr[i].size(); j++){
  15.             cout << arr[i][j] << " \n"[j == arr[i].size()-1];
  16.         }
  17.     }
  18.     cout << "\nblocks = ";
  19.     for(int i = 0; i < block.size(); i++) cout << block[i] << " \n"[i == block.size()-1];
  20.     cout << "new raiz is " << raiz << endl;
  21. }
  22.  
  23. int bucket(int idx){
  24.     int ans = 0, cnt = 0;
  25.     for(int i = 0; i <= raiz; i++) {
  26.         if(arr[i].size()+cnt >= idx) return ans;
  27.         ans++;
  28.         cnt += arr[i].size();
  29.     }
  30.     return ans;
  31. }
  32.  
  33. int index(int idx){
  34.     int cnt = 0;
  35.     for(int i = 0; i <= raiz; i++) {
  36.         if(arr[i].size()+cnt >= idx) return idx-cnt;
  37.         cnt += arr[i].size();
  38.     }
  39.     return 0;
  40. }
  41. void build(){
  42.     raiz = (int) sqrt(n) + 1;
  43.     arr.assign(raiz+1, vector<int> ());
  44.     block.assign(raiz+1, 0);
  45.     int actual = -1;
  46.     for(int i = 0; i < n; i++){
  47.         //cout << i << " " << raiz << " " << (i%raiz) << endl;
  48.         if(i%raiz == 0) actual++;
  49.         arr[actual].push_back(val[i]);
  50.         block[actual] = max(block[actual], val[i]);
  51.     }
  52. }
  53.  
  54. void resize(int idx){
  55.     vector<int> old = arr[idx];
  56.     arr.erase(arr.begin()+idx);
  57.     block[idx] = 0;
  58.     block.insert(block.begin()+idx, 0);
  59.     vector<int> novo;
  60.     for(int i = 0; i < old.size(); i++){
  61.         if(novo.size() == raiz) {
  62.             arr.insert(arr.begin()+idx, novo);
  63.             idx++;
  64.             novo.clear();
  65.         }
  66.         novo.push_back(old[i]);
  67.         block[idx] = max(block[idx], old[i]);
  68.     }
  69.     if(novo.size()){
  70.         arr.insert(arr.begin()+idx, novo);
  71.         novo.clear();
  72.     }
  73. }
  74.  
  75. void insert(int val, int idx){
  76.     int actual = bucket(idx);
  77.     //cout << actual << endl;
  78.  
  79.     idx = index(idx);
  80.     //cout << idx << endl;
  81.     arr[actual].insert(arr[actual].begin() + idx, val);
  82.     //cout << "inseriu\n";
  83.     block[actual] = max(block[actual], val);
  84.     raiz = sqrt(++n) + 1;
  85.     //print();
  86.     if(arr[actual].size() >=  2*raiz) resize(actual);
  87. }
  88.  
  89. int find(int idx, int val){
  90.     int block_idx = bucket(idx);
  91.  
  92.     //cout << block_idx << " " << val << endl;
  93.     int borda = idx-index(idx);
  94.     //cout << idx << " " << borda << endl;
  95.     idx--;
  96.     while(idx >= borda){
  97.         //cout << "initial block\n";
  98.         if(arr[block_idx][idx-borda] > val) return idx+1;
  99.         idx--;
  100.     }
  101.  
  102.     //cout << idx << " " << borda << endl;
  103.     while(idx >= 0){
  104.         //cout << "find a new block\n";
  105.         block_idx--;
  106.         if(block[block_idx] > val) break;
  107.         idx -= arr[block_idx].size();
  108.     }
  109.  
  110.     borda = idx-index(idx);
  111.     while(idx >= borda){
  112.         //cout << "final block\n";
  113.         if(arr[block_idx][idx-borda] > val) return idx+1;
  114.         idx--;
  115.     }
  116.     return 0;
  117. }
  118.  
  119. int main(){
  120.     cin >> n;
  121.     for(int i = 0; i < n; i++) cin >> val[i];
  122.     build();
  123.     //print();
  124.     int q; cin >> q;
  125.     while(q--){
  126.         int type, x, y;  cin >> type >> x >> y;
  127.         if(type == 0){
  128.             insert(y, x);
  129.             //print();
  130.         }else{
  131.             int z = arr[bucket(x)][index(x)-1];
  132.             //cout << "z = " << z << endl;
  133.             cout << find(x, y+z) << endl;
  134.         }
  135.     }
  136.     return 0;
  137. }
Add Comment
Please, Sign In to add comment