Advertisement
Mlxa

Persistent Segment Tree with minPrefix

Feb 18th, 2018
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.92 KB | None | 0 0
  1. #include <cassert>
  2. #include <iostream>
  3. #include <vector>
  4. #include <algorithm>
  5. namespace Mlxa {
  6.     using namespace std;
  7.     typedef long long               ll;
  8.     typedef   signed long long      ull;
  9.    
  10.     #define all(x)              begin(x), end(x)
  11.     #define eol                 '\n'
  12.     #define read                cin
  13.    
  14.     template <ostream &out, class A> inline void
  15.     write (A a)         { out << a; }
  16.     template <ostream &out, class A, class... B> inline void
  17.     write (A a, B... b) { out << a << ' '; write<out>(b...); }
  18.     template <ostream &out, class I> void
  19.     writeseq (I b, I e) { for(I i=b;i!=e;++i) out<<*i<<' '; }
  20.    
  21.     #define print(...)          write<cout>(__VA_ARGS__)
  22.     #define println(...)        print(__VA_ARGS__, eol);
  23.     #define printseq(...)       writeseq<cout>(__VA_ARGS__), print(eol);
  24.     #ifdef AC
  25.         #define addlog(...)     write<cerr>("[D]\t\t\t\t", __VA_ARGS__, eol);
  26.     #else
  27.         #define addlog(...)     (void(0))
  28.     #endif
  29. }   using namespace Mlxa;
  30.  
  31. inline ull mod (ll a, ull m)
  32. {
  33.     ull res = (a % m + m) % m;
  34.     return res;
  35. }
  36.  
  37. struct Node
  38. {
  39.     ll sum;
  40.     Node *l, *r;
  41.     Node (Node *p)
  42.     {
  43.         if (!p) return;
  44.         sum = p->sum;
  45.         l = p->l;
  46.         r = p->r;
  47.     }
  48.     Node (ll s, Node *l, Node *r) : sum(s), l(l), r(r) {}
  49.     Node (Node *l, Node *r) : Node(0, l, r){}
  50.     Node () : Node(nullptr, nullptr) {}
  51.    
  52. }; typedef Node *Ptr;
  53.  
  54. struct Persistent
  55. {
  56.     const static ull MAX_V = 2000000;
  57.     Ptr rt[MAX_V];
  58.     ll curvs;
  59.     #define root rt[0]
  60.     vector<ll> arr;
  61.    
  62.     void build (vector<ll> v)
  63.     {
  64.         ///addlog("void build (vector<ll> v)");
  65.         curvs = 0;
  66.         arr = v;
  67.         root = new Node;
  68.         build(root, 0, arr.size() - 1);
  69.     }
  70.     #undef root
  71.    
  72.     void assign (ull vs, ull x, ull v)
  73.     {
  74.         rt[++ curvs] = assign(rt[vs], 0, arr.size() - 1, x, v);
  75.     }
  76.    
  77.     ull query (ull vs, ull L, ull R)
  78.     {
  79.         return query(rt[vs], 0, arr.size() - 1, L, R);
  80.     }
  81.    
  82.     ull minPrefix (ull vs, ull s)
  83.     {
  84.         return minPrefix(rt[vs], 0, arr.size() - 1, s);
  85.     }
  86.    
  87.     ull minPrefix (Ptr v, ull l, ull r, ll s)
  88.     {
  89.         ull m = (l + r) / 2;
  90.         ///addlog("minPrefix", l, m, r, " ", s, v->sum);
  91.         if (l == r) {
  92.             if (s <= v->sum)
  93.                 return l;
  94.             else
  95.                 return -1;
  96.         }
  97.         if (v->l && v->l->sum >= s)
  98.             return minPrefix(v->l, l, m, s);
  99.         else if (v->r)
  100.             return minPrefix(v->r, m+1, r, s - v->l->sum);
  101.         return -1;
  102.     }
  103.    
  104.     void build (Ptr v, ull l, ull r)
  105.     {
  106.         ///addlog("void build (Ptr v, ull l, ull r)");
  107.         ///addlog("                       ", l, r);
  108.         assert(v);
  109.         assert(l <= r);
  110.         if (l == r) {
  111.             v->sum = arr[l];
  112.             return;
  113.         }
  114.         ull m = (l + r) / 2;
  115.         v->l = new Node;
  116.         v->r = new Node;
  117.         build(v->l, l, m);
  118.         build(v->r, m + 1, r);
  119.         v->sum = v->l->sum + v->r->sum;
  120.     }
  121.    
  122.     Ptr assign (Ptr v, ull l, ull r, ull x, ull val)
  123.     {
  124.         ///addlog("Ptr assign (Ptr v, ull l, ull r, ull x, ull val)");
  125.         ///addlog("                      ", l, r, x, val);
  126.         assert(v);
  127.         assert(l <= x && x <= r);
  128.         Ptr nv = new Node(v);
  129.         if (l < r) {
  130.             ull m = (l + r) / 2;
  131.             if (x <= m)
  132.                 nv->l = assign(nv->l, l, m, x, val);
  133.             else
  134.                 nv->r = assign(nv->r, m + 1, r, x, val);
  135.             nv->sum = nv->l->sum + nv->r->sum;
  136.         }
  137.         else nv->sum = val;
  138.         return nv;
  139.     }
  140.    
  141.     ull query (Ptr v, ull l, ull r, ull L, ull R)
  142.     {
  143.         assert(v);
  144.         assert(l <= L && L <= R && R <= r);
  145.         ull m = (l + r) / 2;
  146.         /// Если запрос полностью покрывает
  147.         if (l == L && r == R) return v->sum;
  148.         ull res = 0;
  149.         /// Если затрагивает левого сына
  150.         if (L <= m) res += query(v->l, l, m, L, min(m, R));
  151.         /// Если затрагивает правого сына
  152.         if (R > m)  res += query(v->r, m+1, r, max(m+1, L), R);
  153.         return res;
  154.     }
  155. };
  156.  
  157.  
  158. ull N, M, Q, p = 0;
  159. vector<ll> a, x, y;
  160. vector<ull> last;
  161. Persistent first;
  162.  
  163. void start ()
  164. {
  165.     read >> N >> M;
  166.     a.resize(N);
  167.     for (ull i = 0; i < N; ++ i)
  168.         read >> a[i];
  169.     read >> Q;
  170.    
  171.     last.assign(M + 10, 0);
  172.     first.build(vector<ull>(N, 0));
  173. }
  174.  
  175. // Версии идут наоборот
  176. void prepare ()
  177. {
  178.     for (ull i = N - 1; i != (ull)-1; -- i) {
  179.         first.assign(first.curvs, last[a[i]], 0);
  180.         last[a[i]] = i;
  181.         first.assign(first.curvs, i, 1);
  182.     }
  183. }
  184.  
  185. ull solve (ull l, ull k)
  186. {
  187.     ///l -> N-1-l
  188.     ull vers = N-1-l;
  189.     ///addlog("solve", l, k);
  190.     /**vector<ull> rem(N, 5);
  191.     for (ull i = 0; i < N; ++ i)
  192.         rem[i] = first.query(2+2*vers, i, i);
  193.     printseq(all(rem));**/
  194.    
  195.     ull res = first.minPrefix(2+2*vers, k);
  196.     ///println("result: r ==", res + 1);
  197.     if (res >= 0) return res + 1;
  198.     return 0;
  199. }
  200.  
  201.  
  202.  
  203. int main ()
  204. {
  205.     start();
  206.    
  207.     prepare();
  208.    
  209.     /*println("\nDEBUG!");
  210.     vector<ull> rem(N, 5);
  211.     for (ull vers = 0; vers < N; ++ vers) {
  212.     for (ull i = 0; i < N; ++ i)
  213.         rem[i] = first.query(2+2*vers, i, i);
  214.     printseq(all(rem)); }*/
  215.    
  216.     for (ull i = 0; i < Q; ++ i) {
  217.         ull x, y, l, k;
  218.         read >> x >> y;
  219.         l = mod(x + p, N);
  220.         k = mod(y + p, M) + 1;
  221.         ull r = solve (l, k);
  222.         println(r);
  223.         p = r;
  224.     }
  225.    
  226.     return 0;
  227. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement