zoukankan      html  css  js  c++  java
  • [ZJOI2016]大森林

    (貌似整个代码不能用 $makeroot$ ?是因为是有根树?)

    因为是区间操作,所以可以考虑在区间内与区间外的差异

    对于操作 $1$ ,可以看作一个生成节点包含了到下一个 $1$ 操作之间长出的节点,那么对于一个操作 $l, r$ ,相当于是在 $l$ 处将当前生成节点及其包含的节点整个移植到它更改后的位置,到 $r + 1$ 时再移植回去,所以可以考虑将一个 $1$ 操作分解为两个操作(一个移植,一个移植回去),故可以将所有操作按端点、时间排序(以及同位置修改操作必定在查询操作前,因为可以先把树建完再查询对结果没有影响),扫描一遍即可

    同时,为了方便移植,将每个生成节点看作新建的一个虚点

    对于操作 $0$ ,直接在虚点下 $link$ 即可,因为就算已经建了一些对于当前操作不存在的虚点,也不会对答案造成影响

    对于操作 $2$ ,无法正面在 $LCT$ 上算出两点的距离,故可考虑差分,得到 $Ans = Sum_x + Sum_y - 2 * Sum_{lca}$ ,其中实点贡献为 $1$ ,虚点贡献为 $0$

    对于求 $LCA$ ,先 $access (y)$ ,再在 $access (x)$ 的时候得到的最后一个跳虚边的点即是它们的 $LCA$

    代码

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 
      6 using namespace std;
      7 
      8 const int MAXN = 3e05 + 10;
      9 
     10 struct QuerySt {
     11     int pos, time;
     12     int x, y;
     13 
     14     QuerySt () {}
     15     QuerySt (int fpos, int ftime, int fx, int fy) :
     16         pos (fpos), time (ftime), x (fx), y (fy) {}
     17 
     18     bool operator < (const QuerySt& p) const {
     19         return pos == p.pos ? time < p.time : pos < p.pos;
     20     }
     21 } ;
     22 QuerySt Query[MAXN];
     23 int que = 0;
     24 
     25 int N, M;
     26 
     27 int father[MAXN]= {0};
     28 int son[MAXN][2]= {0};
     29 int Sum[MAXN]= {0}, value[MAXN]= {0};
     30 
     31 int isroot (int p) {
     32     return son[father[p]][0] != p && son[father[p]][1] != p;
     33 }
     34 int sonbel (int p) {
     35     return son[father[p]][1] == p;
     36 }
     37 void pushup (int p) {
     38     Sum[p] = Sum[son[p][0]] + Sum[son[p][1]] + value[p];
     39 }
     40 void rotate (int p) {
     41     int fa = father[p], anc = father[fa];
     42     int s = sonbel (p);
     43     son[fa][s] = son[p][s ^ 1];
     44     if (son[fa][s])
     45         father[son[fa][s]] = fa;
     46     if (! isroot (fa))
     47         son[anc][sonbel (fa)] = p;
     48     father[p] = anc;
     49     son[p][s ^ 1] = fa, father[fa] = p;
     50     pushup (fa), pushup (p);
     51 }
     52 void splay (int p) {
     53     for (int fa = father[p]; ! isroot (p); rotate (p), fa = father[p])
     54         if (! isroot (fa))
     55             sonbel (p) == sonbel (fa) ? rotate (fa) : rotate (p);
     56 }
     57 int Access (int p) {
     58     int tp = 0;
     59     for ( ; p; tp = p, p = father[p])
     60         splay (p), son[p][1] = tp, pushup (p);
     61     return tp;
     62 }
     63 void link (int x, int y) { // 注意此时没有makeroot所以需要注意是将y连到x下
     64     splay (y);
     65     father[y] = x;
     66 }
     67 void cut (int x) {
     68     Access (x), splay (x);
     69     father[son[x][0]] = 0, son[x][0] = 0;
     70     pushup (x);
     71 }
     72 
     73 int totq = 0;
     74 int ans[MAXN]= {0};
     75 void Solve () {
     76     sort (Query + 1, Query + que + 1);
     77     for (int i = 1; i <= que; i ++) {
     78         int time = Query[i].time;
     79         int x = Query[i].x, y = Query[i].y;
     80         if (time > 0) {
     81             Access (x), splay (x), ans[time] += Sum[x];
     82             int lca = Access (y);
     83             splay (y), ans[time] += Sum[y];
     84             Access (lca), splay (lca), ans[time] -= (Sum[lca] << 1);
     85         }
     86         else
     87             cut (x), link (y, x);
     88     }
     89 }
     90 
     91 int getnum () {
     92     int num = 0;
     93     char ch = getchar ();
     94 
     95     while (! isdigit (ch))
     96         ch = getchar ();
     97     while (isdigit (ch))
     98         num = (num << 3) + (num << 1) + ch - '0', ch = getchar ();
     99 
    100     return num;
    101 }
    102 
    103 int ind[MAXN]= {0};
    104 int liml[MAXN], limr[MAXN];
    105 int nodes = 1;
    106 int main () {
    107     N = getnum (), M = getnum ();
    108     int lastr = 1, real = 1;
    109     ind[1] = Sum[1] = value[1] = 1, liml[1] = 1, limr[1] = N;
    110     link (1, nodes = lastr = 2);
    111     for (int i = 1; i <= M; i ++) {
    112         int opt = getnum ();
    113         if (opt == 0) {
    114             int l = getnum (), r = getnum ();
    115             link (lastr, ind[++ real] = ++ nodes);
    116             value[nodes] = Sum[nodes] = 1;
    117             liml[real] = l, limr[real] = r;
    118         }
    119         else if (opt == 1) {
    120             int l = getnum (), r = getnum (), x = getnum ();
    121             l = max (l, liml[x]), r = min (r, limr[x]);
    122             if (l > r)
    123                 continue;
    124             link (lastr, ++ nodes);
    125             Query[++ que] = QuerySt (l, i - M, nodes, ind[x]); // 由nodes离开link向index[x]
    126             Query[++ que] = QuerySt (r + 1, i - M, nodes, lastr);
    127             lastr = nodes;
    128         }
    129         else if (opt == 2) {
    130             int x = getnum (), u = getnum (), v = getnum ();
    131             Query[++ que] = QuerySt (x, ++ totq, ind[u], ind[v]); // 由index[u]到index[v]的距离
    132         }
    133     }
    134     Solve ();
    135     for (int i = 1; i <= totq; i ++)
    136         printf ("%d
    ", ans[i]);
    137 
    138     return 0;
    139 }
    140 
    141 /*
    142 5 5
    143 0 1 5
    144 1 2 4 2
    145 0 1 4
    146 2 1 1 3
    147 2 2 1 3
    148 */
  • 相关阅读:
    Changing Icon File Of Push Button At Runtime In Oracle Forms 6i
    Set Font Properties On Mouse Hover Of Push Button And Text Items At Run time In Oracle Forms
    Change An Item Property Using Set_Item_Property In Oracle Forms
    Calling / Running a report in Oracle forms 10g / 11g
    Change Or Set Report Object Property At Run Time In Oracle Forms Using Set_Report_Object_Property Command
    Refresh / Updating a form screen in Oracle D2k Forms 6i
    Know How And When To Use System.Message_Level To Control Messages In Oracle Forms
    Perform Cut Copy Paste Operations Using Cut_Region Copy_Region Paste_Region Commands In Oracle Forms
    CHECKBOX_CHECKED built-in in Oracle D2k Forms
    Limiting To Select Only 5 Check Boxes Out Of Ten In Oracle Forms
  • 原文地址:https://www.cnblogs.com/Colythme/p/10179977.html
Copyright © 2011-2022 走看看