• [bzoj1103][POI2007]大都市meg


    题目链接

    这道题用来理解LCT还是蛮不错的,如果是笨重的LCT完全体就会在洛谷上卡常T掉第4组,但是这道题明显可以省略掉很多多余操作。

    我们先看看如果按照正常的LCT,会有这样一些操作:

    inline void makeroot(register int x) {
        access(x); splay(x); pushr(x);
    }
    inline void split(register int x, register int y) {
        makeroot(x); access(y); splay(y);
    }
    inline void Link(register int x, register int y) {
        makeroot(x); fa[x] = y;
    }

    makeroot为换根,Link为连边,split为连出棵splay:x-y并将y变为根。

    在正常的LCT题目中换根是必不可少的,但在本题中却可以省掉。

    因为题目中保证以1为根,且查询为1到x的距离,这样就保证了根节点可以不变,如果在建树时可以让1节点做原树的根就可以省掉换根。

    所以换根操作就可以果断放弃掉,大大的优化了常数。

    所以就可以过啦!

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const unsigned  int maxn = 250010;
     5 int ch[maxn][2], val[maxn], sum[maxn], fa[maxn];
     6 inline bool isroot(int x) {
     7     return ch[fa[x]][0] != x && ch[fa[x]][1] != x;
     8 }
     9 inline void pushup(int x) {
    10     sum[x] = sum[ch[x][0]] + sum[ch[x][1]] + val[x];
    11 }
    12 inline void rotate(int x) {
    13     int y = fa[x], z = fa[y];
    14     int k = ch[y][1] == x;
    15     if (!isroot(y))
    16         ch[z][ch[z][1] == y] = x;
    17     fa[x] = z; ch[y][k] = ch[x][k ^ 1]; fa[ch[x][k ^ 1]] = y;
    18     ch[x][k ^ 1] = y; fa[y] = x;
    19     pushup(y); pushup(x);
    20 }
    21 inline void splay(int x) {
    22     while (!isroot(x)) {
    23         int y = fa[x];
    24         int z = fa[y];
    25         if (!isroot(y))
    26             rotate((ch[y][0] == x) ^ (ch[z][0] == y) ? x : y);
    27         rotate(x);
    28     }
    29     pushup(x);
    30 }
    31 inline void access(int x) {
    32     for (int y = 0; x; x = fa[y = x])
    33         splay(x), ch[x][1] = y, pushup(x);
    34 }
    35 char s[2];
    36 int main() {
    37     int n, m, x, y;
    38     scanf("%d", &n);
    39     for (int i = 2; i <= n; ++i)
    40         val[i] = 1;
    41     for (int i = 1; i < n; ++i) {
    42         scanf("%d%d", &x, &y);
    43         if (x > y)
    44             swap(x, y);
    45         fa[y] = x;
    46     }
    47     scanf("%d", &m);
    48     m += n - 1;
    49     while (m--) {
    50         scanf("%s", s);
    51         if (s[0] == 'A') {
    52             scanf("%d%d", &x, &y);
    53             if (x > y)swap(x, y);
    54             splay(y);
    55             val[y] = 0, pushup(y);
    56         }
    57         else {
    58             scanf("%d", &x);
    59             access(x); splay(x);
    60             printf("%d
    ", sum[x]);
    61         }
    62     }
    63 }
  • 相关阅读:
    23 情态动词+完成时
    22 情态动词否定和疑问
    青山有幸埋忠骨,白铁无辜铸佞臣。
    Modern Perl
    en_windows_10_enterprise_ltsc_2019_x64_dvd_5795bb03
    Destinos & Nuevos Destinos
    TVB <十兄弟>
    Great Udemy Courses
    assembly language reference
    Alex Jones
  • 原文地址:https://www.cnblogs.com/sainsist/p/11443344.html
Copyright © 2020-2023  润新知