EntropyIncreaser

Jabby's shadow

Sep 4th, 2019
510
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.81 KB | None | 0 0
  1. #include <cstdio>
  2. #include <cctype>
  3. #include <algorithm>
  4.  
  5. struct IO_Tp
  6. {
  7.     const static int _I_Buffer_Size = 4 << 20;
  8.     char _I_Buffer[_I_Buffer_Size], *_I_pos = _I_Buffer;
  9.    
  10.     const static int _O_Buffer_Size = 4 << 20;
  11.     char _O_Buffer[_O_Buffer_Size], *_O_pos = _O_Buffer;
  12.    
  13.     IO_Tp() { fread(_I_Buffer, 1, _I_Buffer_Size, stdin); }
  14.     ~IO_Tp() { fwrite(_O_Buffer, 1, _O_pos - _O_Buffer, stdout); }
  15.    
  16.     IO_Tp &operator>>(int &res)
  17.     {
  18.         res = 0;
  19.         while (!isdigit(*_I_pos))
  20.             ++_I_pos;
  21.         do
  22.             res = res * 10 + (*_I_pos++ & 15);
  23.         while (isdigit(*_I_pos));
  24.         return *this;
  25.     }
  26.    
  27.     char getop()
  28.     {
  29.         while (!isdigit(*_I_pos))
  30.             ++_I_pos;
  31.         return *_I_pos++ & 15;
  32.     }
  33.    
  34.     IO_Tp &operator<<(int n)
  35.     {
  36.         static char _buf[10];
  37.         char* _pos = _buf;
  38.         do
  39.             *_pos++ = '0' + n % 10;
  40.         while (n /= 10);
  41.         while (_pos != _buf)
  42.             *_O_pos++ = *--_pos;
  43.         return *this;
  44.     }
  45.    
  46.     IO_Tp &operator<<(char ch)
  47.     {
  48.         *_O_pos++ = ch;
  49.         return *this;
  50.     }
  51. } IO;
  52.  
  53. const bool compress = false, rake = true;
  54.  
  55. struct Splay_Tree
  56. {
  57.     static Splay_Tree *Null;
  58.    
  59.     void *operator new(size_t size);
  60.     void *operator new[](size_t size);
  61.     void operator delete(void *ptr);
  62.  
  63.     Splay_Tree *ch[3], *parent;
  64.     bool rev;
  65.     bool color, pc[2];
  66.     int length, dist[2][2], res[2], pdist[2][2], pres[2];
  67.     char lazy;
  68.    
  69.     Splay_Tree() : rev(false), color(0), length(0), lazy(-1)
  70.     {
  71.         static bool _init = false;
  72.         if (!_init)
  73.         {
  74.             _init = true;
  75.             Null = new Splay_Tree;
  76.             Null->ch[0] = Null->ch[1] = Null->ch[2] = Null->parent = Null;
  77.             Null->pc[0] = Null->pc[1] = true;
  78.         }
  79.         ch[0] = ch[1] = ch[2] = parent = Null;
  80.         pc[0] = true, pc[1] = false;
  81.         length = dist[0][0] = dist[0][1] = dist[1][0] = dist[1][1] = res[0] = res[1] = 0;
  82.         pdist[0][0] = pdist[0][1] = pdist[1][0] = pdist[1][1] = pres[0] = pres[1] = 0;
  83.     }
  84.    
  85.     bool is_root() const
  86.     {
  87.         return parent->ch[0] != this && parent->ch[1] != this;
  88.     }
  89.    
  90.     template<const bool type>
  91.     void pushup();
  92.    
  93.     template<const bool type>
  94.     void pushdown();
  95.    
  96.     void reverse()
  97.     {
  98.         rev ^= 1, std::swap(ch[0], ch[1]);
  99.         std::swap(dist[0][0], dist[1][0]), std::swap(dist[0][1], dist[1][1]);
  100.         std::swap(res[0], res[1]);
  101.         std::swap(pdist[0][0], pdist[1][0]), std::swap(pdist[0][1], pdist[1][1]);
  102.     }
  103.    
  104.     bool dir() const
  105.     {
  106.         return parent->ch[1] == this;
  107.     }
  108.    
  109.     Splay_Tree *sch(const int d, Splay_Tree *c)
  110.     {
  111.         return ch[d] = c, c->parent = this;
  112.     }
  113.    
  114.     void modify(const bool _c)
  115.     {
  116.         if (pc[0] && pc[1])
  117.             return;
  118.         lazy = _c;
  119.         this->color = _c;
  120.         pc[_c] = true, pc[!_c] = false;
  121.         dist[0][_c] = pdist[0][_c], dist[1][_c] = pdist[1][_c];
  122.         dist[0][!_c] = dist[1][!_c] = 0;
  123.         res[0] = res[1] = pres[_c];
  124.     }
  125.    
  126.     template<const bool type>
  127.     void rotate()
  128.     {
  129.         Splay_Tree *p = parent;
  130.         p->pushdown<type>(), pushdown<type>();
  131.         bool d = dir();
  132.         if (parent = p->parent, p->parent != Splay_Tree::Null)
  133.         {
  134.             if (p->parent->ch[2] == p)
  135.                 p->parent->ch[2] = this;
  136.             else
  137.                 p->parent->ch[p->dir()] = this;
  138.         }
  139.         p->sch(d, ch[!d])->pushup<type>(), sch(!d, p)->pushup<type>();  
  140.     }
  141.    
  142.     template<const bool type>
  143.     Splay_Tree *splay(Splay_Tree *p = Null)
  144.     {
  145.         for (pushdown<type>(); parent != p && !is_root(); rotate<type>())
  146.             if (parent->parent != p && !parent->is_root())
  147.                 parent->parent->pushdown<type>(), (parent->dir() == dir() ? parent : this)->rotate<type>();
  148.         return this;
  149.     }
  150.    
  151.     template<const bool type>
  152.     Splay_Tree *splay_m(const bool d)
  153.     {
  154.         Splay_Tree *o = this;
  155.         while (o->pushdown<type>(), o->ch[d] != Splay_Tree::Null)
  156.             o = o->ch[d];
  157.         return o->splay<type>(parent);
  158.     }
  159. };
  160. Splay_Tree *Splay_Tree::Null;
  161.  
  162. const int Max_N = 100005;
  163.  
  164. const int _M_size = Max_N * 3;
  165. char _M[_M_size * sizeof(Splay_Tree)], *_M_cur = _M + sizeof(_M);
  166. void *_M_rc[_M_size], **_M_rc_cur = _M_rc;
  167.  
  168. inline void *Splay_Tree::operator new(size_t size) { return _M_rc_cur != _M_rc ? *--_M_rc_cur : _M_cur -= size; }
  169. inline void *Splay_Tree::operator new[](size_t size) { return _M_cur -= size; }
  170. inline void Splay_Tree::operator delete(void *ptr) { *_M_rc_cur++ = ptr; }
  171.  
  172. template<>
  173. inline void Splay_Tree::pushup<compress>()
  174. {
  175.     pc[color] = ch[0]->pc[color] && ch[1]->pc[color], pc[!color] = false;
  176.     length = ch[0]->length + ch[1]->length;
  177.     dist[0][0] = ch[0]->dist[0][0], dist[0][1] = ch[0]->dist[0][1];
  178.     dist[1][0] = ch[1]->dist[1][0], dist[1][1] = ch[1]->dist[1][1];
  179.     res[0] = ch[0]->res[0], res[1] = ch[1]->res[1];
  180.     if (ch[0]->pc[color])
  181.     {
  182.         dist[0][color] = std::max(dist[0][color], ch[0]->length + std::max(ch[1]->dist[0][color], ch[2]->dist[0][color]));
  183.         res[0] = std::max(std::max(res[0], std::max(ch[1]->dist[0][color] ? ch[1]->res[0] : 0, ch[2]->res[color])), std::max(ch[0]->dist[1][color] + ch[1]->dist[0][color], std::max(ch[0]->dist[1][color], ch[1]->dist[0][color]) + ch[2]->dist[0][color]));
  184.     }
  185.     if (ch[1]->pc[color])
  186.     {
  187.         dist[1][color] = std::max(dist[1][color], ch[1]->length + std::max(ch[0]->dist[1][color], ch[2]->dist[0][color]));
  188.         res[1] = std::max(std::max(res[1], std::max(ch[0]->dist[1][color] ? ch[0]->res[1] : 0, ch[2]->res[color])), std::max(ch[0]->dist[1][color] + ch[1]->dist[0][color], std::max(ch[0]->dist[1][color], ch[1]->dist[0][color]) + ch[2]->dist[0][color]));
  189.     }
  190.     pdist[0][0] = std::max(ch[0]->pdist[0][0], ch[0]->length + std::max(ch[1]->pdist[0][0], ch[2]->dist[0][0]));
  191.     pdist[0][1] = std::max(ch[0]->pdist[0][1], ch[0]->length + std::max(ch[1]->pdist[0][1], ch[2]->dist[0][1]));
  192.     pdist[1][0] = std::max(ch[1]->pdist[1][0], ch[1]->length + std::max(ch[0]->pdist[1][0], ch[2]->dist[0][0]));
  193.     pdist[1][1] = std::max(ch[1]->pdist[1][1], ch[1]->length + std::max(ch[0]->pdist[1][1], ch[2]->dist[0][1]));
  194.     pres[0] = std::max(std::max(std::max(ch[0]->pres[0], ch[1]->pres[0]), ch[2]->res[0]), std::max(ch[0]->pdist[1][0] + ch[1]->pdist[0][0], std::max(ch[0]->pdist[1][0], ch[1]->pdist[0][0]) + ch[2]->dist[0][0]));
  195.     pres[1] = std::max(std::max(std::max(ch[0]->pres[1], ch[1]->pres[1]), ch[2]->res[1]), std::max(ch[0]->pdist[1][1] + ch[1]->pdist[0][1], std::max(ch[0]->pdist[1][1], ch[1]->pdist[0][1]) + ch[2]->dist[0][1]));
  196. }
  197.  
  198. template<>
  199. inline void Splay_Tree::pushup<rake>()
  200. {
  201.     dist[0][0] = std::max(std::max(ch[0]->dist[0][0], ch[1]->dist[0][0]), ch[2]->dist[0][0]);
  202.     dist[0][1] = std::max(std::max(ch[0]->dist[0][1], ch[1]->dist[0][1]), ch[2]->dist[0][1]);
  203.     res[0] = std::max(std::max(ch[0]->dist[0][0] + ch[1]->dist[0][0], ch[2]->dist[0][0] + std::max(ch[0]->dist[0][0], ch[1]->dist[0][0])), std::max(ch[2]->dist[0][0] ? ch[2]->res[0] : 0, std::max(ch[0]->res[0], ch[1]->res[0])));
  204.     res[1] = std::max(std::max(ch[0]->dist[0][1] + ch[1]->dist[0][1], ch[2]->dist[0][1] + std::max(ch[0]->dist[0][1], ch[1]->dist[0][1])), std::max(ch[2]->dist[0][1] ? ch[2]->res[0] : 0, std::max(ch[0]->res[1], ch[1]->res[1])));
  205. }
  206.  
  207. template<>
  208. inline void Splay_Tree::pushdown<compress>()
  209. {
  210.     if (rev)
  211.         ch[0]->reverse(), ch[1]->reverse(), rev = false;
  212.     if (lazy != -1)
  213.         ch[0]->modify(lazy), ch[1]->modify(lazy), lazy = -1;
  214. }
  215.  
  216. template<>
  217. inline void Splay_Tree::pushdown<rake>() { }
  218.  
  219. void splay_splice(Splay_Tree *o)
  220. {
  221.     o->splay<rake>();
  222.     o = o->parent->splay<compress>();
  223.     Splay_Tree *c = o->ch[2];
  224.     c->pushdown<rake>();
  225.     if (o->ch[1] != Splay_Tree::Null)
  226.         std::swap(o->ch[1]->parent, c->ch[2]->parent), std::swap(o->ch[1], c->ch[2]);
  227.     else
  228.     {
  229.         o->sch(1, c->ch[2]);
  230.         if (c->ch[0] != Splay_Tree::Null)
  231.             c->ch[0]->splay_m<rake>(1), c->ch[0]->sch(1, c->ch[1]), o->ch[2] = c->ch[0];
  232.         else
  233.             c->ch[1]->pushdown<rake>(), o->ch[2] = c->ch[1];
  234.         delete c, c = o->ch[2], c->parent = o;
  235.     }
  236.     c->pushup<rake>(), o->pushup<compress>(), o->ch[1]->rotate<compress>();
  237. }
  238.  
  239. void access(Splay_Tree *o)
  240. {
  241.     o->splay<compress>();
  242.     if (o->ch[1] != Splay_Tree::Null)
  243.     {
  244.         Splay_Tree *c = new Splay_Tree;
  245.         c->sch(0, o->ch[2]), c->sch(2, o->ch[1]), c->pushup<rake>();
  246.         o->ch[1] = Splay_Tree::Null, o->sch(2, c), o->pushup<compress>();
  247.     }
  248.     while (o->parent != Splay_Tree::Null)
  249.         splay_splice(o->parent);
  250. }
  251.  
  252. inline void evert(Splay_Tree *o)
  253. {
  254.     access(o), o->reverse(), o->pushdown<compress>();
  255. }
  256.  
  257. inline void link(Splay_Tree *o1, Splay_Tree *o2, const int c)
  258. {
  259.     access(o1), evert(o2), o2->pushdown<compress>();
  260.     Splay_Tree *e = new Splay_Tree;
  261.     e->pc[1] = true, e->length = c;
  262.     o2->sch(0, e)->pushup<compress>(), o1->sch(1, o2)->pushup<compress>();
  263. }
  264.  
  265. int N, M;
  266. int p[Max_N];
  267. Splay_Tree *node0;
  268. #define node(x) (node0 + x)
  269.  
  270. int main(int argc, char **argv)
  271. {
  272.     IO >> N;
  273.     node0 = new Splay_Tree[N + 1];
  274.    
  275.     for (int i = 2; i <= N; ++i)
  276.         IO >> p[i];
  277.     for (int i = 2, c; i <= N; ++i)
  278.         IO >> c, link(node(i), node(p[i]), c);
  279.    
  280.     IO >> M;
  281.     while (M--)
  282.         switch (IO.getop())
  283.         {
  284.             int v, w, c;
  285.            
  286.             case 1:
  287.                 IO >> v;
  288.                 access(node(v)), node(v)->res[1] ? IO << node(v)->res[1] << '\n' : IO << 'Q' << 'w' << 'Q' << '\n';
  289.                 break;
  290.            
  291.             case 2:
  292.                 IO >> v >> w >> c;
  293.                 evert(node(v)), access(node(w)), node(w)->modify(c - 1);
  294.                 break;
  295.         }
  296.    
  297.     return 0;
  298. }
Advertisement
Add Comment
Please, Sign In to add comment