Advertisement
Alex239

Untitled

Dec 26th, 2017
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.06 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4. typedef long long nagai;
  5.  
  6. #include "grader.h"
  7.  
  8. nagai gcd(nagai a, nagai b)
  9. {
  10.     while (b)
  11.         a = a % b, swap(a, b);
  12.     return a;
  13. }
  14.  
  15. template<int H>
  16. struct sl
  17. {
  18.     struct nd
  19.     {
  20.         vector<nd*> ri;
  21.         vector<nagai> gcd;
  22. //      vector<int> len;
  23.         pair<int, int> x;
  24.         inline int sz()
  25.         {
  26.             return ri.size();
  27.         }
  28.     };
  29.     nd* header;
  30.     sl()
  31.     {
  32.         header = new nd;
  33.         header->ri.resize(H, nullptr);
  34.         header->gcd.resize(H, 0);
  35.         header->x = {-1, -1};
  36.         //header->len.resize(H, 0);
  37.     }
  38.     nd* last[H];
  39.     int len[H];
  40.     void go(pair<int, int> to)
  41.     {
  42.         nd* cur = header;
  43.         for (int i = H - 1; i >= 0; --i)
  44.         {
  45.             if (cur->ri[i] && cur->ri[i]->x < to)
  46.                 cur = cur->ri[i];
  47.             last[i] = cur;
  48.         }
  49.     }
  50.     inline nagai calc(nd* a, nd* b, int i)
  51.     {
  52.         nagai g = a->gcd[i];
  53.         while (!b && a->ri[i] || b && a->ri[i] && a->ri[i]->x < b->x)
  54.             a = a->ri[i], g = gcd(g, a->gcd[i]);
  55.         //cerr << a->x << ' ' << (b ? b->x : -2) << ' ' << i << ' ' << g << endl;
  56.         return g;
  57.     }
  58.     void insert(pair<int, int> ind, nagai val)
  59.     {
  60.         go(ind);
  61.         nd* nw = new nd;
  62.         nw->x = ind;
  63.         for (int i = 0, add = 1; i < H; add &= rand(), ++i)
  64.         {
  65.             if (add)
  66.             {
  67.                 if (i > 0)
  68.                 {
  69.                     nagai g = calc(last[i], nw, i - 1);
  70.                     nagai g1 = calc(nw, last[i]->ri[i], i - 1);
  71.                     //cerr << "kek " << g << ' ' << last[i]->x << ' ' << last[i]->gcd[i - 1] << endl;
  72.                     last[i]->gcd[i] = g;
  73.                     nw->gcd.push_back(g1);
  74.                 }
  75.                 else
  76.                     nw->gcd.push_back(val);
  77.                 nw->ri.push_back(last[i]->ri[i]);
  78.                 last[i]->ri[i] = nw;
  79.             }
  80.             else
  81.             {
  82.                 last[i]->gcd[i] = gcd(last[i]->gcd[i], val);
  83.             }
  84.         }
  85.     }
  86.     void erase(pair<int, int> ind)
  87.     {
  88.         go(ind);
  89.         for (int i = 0; i < H; ++i)
  90.         {
  91.             if (last[i]->ri[i] && last[i]->ri[i]->x == ind)
  92.             {
  93.                 if (i)
  94.                     last[i]->gcd[i] = calc(last[i], last[i]->ri[i]->ri[i], i - 1);
  95.                 last[i]->ri[i] = last[i]->ri[i]->ri[i];
  96.             }
  97.             else
  98.                 last[i]->gcd[i] = calc(last[i], last[i]->ri[i], i - 1);
  99.         }
  100.     }
  101.     void print()
  102.     {
  103.         for (int i = 0; i < H; ++i)
  104.         {
  105.             auto v = header;
  106.             while (v)
  107.                 cerr << '{' << v->x.first << ',' << v->x.second << '}' << ',' << v->gcd[i] << ' ', v = v->ri[i];
  108.             cerr << endl;
  109.         }
  110.     }
  111.     nagai get(pair<int, int> l, pair<int, int> r)
  112.     {
  113.         nagai g = 0;
  114.         go(l);
  115.         nd* kek = last[0]->ri[0];
  116.         if (!kek)
  117.             return 0;
  118.         //cerr << kek->x.first << ' ' << kek->x.second << endl;
  119.         for (int i = 0; i < H; ++i)
  120.             while (i < kek->sz() && i + 1 >= kek->sz() && kek->ri[i] && kek->ri[i]->x < r)
  121.                 g = gcd(g, kek->gcd[i]), kek = kek->ri[i];
  122.         //cerr << kek->x.first << ' ' << kek->x.second << ' ' << g << endl;
  123.         for (int i = H - 1; i >= 0; --i)
  124.             while (i < kek->sz() && kek->ri[i] && kek->ri[i]->x < r)
  125.                 g = gcd(g, kek->gcd[i]), kek = kek->ri[i];
  126.         //cerr << kek->x.first << ' ' << kek->x.second << ' ' << g << endl;
  127.         if (kek->x < r)
  128.             g = gcd(g, kek->gcd[0]);
  129.         return g;
  130.     }
  131. };
  132.  
  133. struct nd
  134. {
  135.     nd* le;
  136.     nd* ri;
  137.     sl<18> skip;
  138.     nd()
  139.         : le(nullptr), ri(nullptr)
  140.     {}
  141.     void children()
  142.     {
  143.         if (!le)
  144.             le = new nd();
  145.         if (!ri)
  146.             ri = new nd();
  147.     }
  148.     void add(int l, int r, int x, int y, nagai val, bool add)
  149.     {
  150.         if (l > x || r <= x)
  151.             return;
  152.         if (add)
  153.             skip.insert({y, x}, val);
  154.         else
  155.             skip.erase({y, x});
  156.         if (r - l == 1)
  157.             return;
  158.         children();
  159.         int m = (l + r) / 2;
  160.         le->add(l, m, x, y, val, add);
  161.         ri->add(m, r, x, y, val, add);
  162.     }
  163.     nagai get(int l, int r, int ql1, int qr1, int ql2, int qr2)
  164.     {
  165.         //skip.print();
  166.         if (l >= qr1 || ql1 >= r)
  167.             return 0;
  168.         if (ql1 <= l && r <= qr1)
  169.             return skip.get({ql2, ql1}, {qr2, ql1});
  170.         children();
  171.         int m = (l + r) / 2;
  172.         return gcd(le->get(l, m, ql1, m, ql2, qr2),
  173.                 ri->get(m, r, m, qr1, ql2, qr2));
  174.     }
  175. };
  176.  
  177. nd* rt = new nd;
  178.  
  179. int MX = 1000000000;
  180. set<pair<int, int>> p;
  181.  
  182. void init(int R, int C)
  183. {
  184.     MX = R;
  185. }
  186.  
  187. void update(int x, int y, long long t)
  188. {
  189.     if (p.count({x, y}))
  190.         rt->add(0, MX, x, y, t, 0);
  191.     rt->add(0, MX, x, y, t, 1);
  192.     p.insert({x, y});
  193. }
  194.  
  195. long long calculate(int xl, int yl, int xr, int yr)
  196. {
  197.     return rt->get(0, MX, xl, xr + 1, yl, yr + 1);
  198. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement