• BZOJ 3282: Tree [LCT]


    3282: Tree

    Time Limit: 30 Sec  Memory Limit: 512 MB
    Submit: 1677  Solved: 744
    [Submit][Status][Discuss]

    Description

    给定N个点以及每个点的权值,要你处理接下来的M个操作。操作有4种。操作从0到3编号。点从1到N编号。

    0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。保证x到y是联通的。

    1:后接两个整数(x,y),代表连接x到y,若x到Y已经联通则无需连接。

    2:后接两个整数(x,y),代表删除边(x,y),不保证边(x,y)存在。

    3:后接两个整数(x,y),代表将点X上的权值变成Y。

    Input

    第1行两个整数,分别为N和M,代表点数和操作数。

    第2行到第N+1行,每行一个整数,整数在[1,10^9]内,代表每个点的权值。

    第N+2行到第N+M+1行,每行三个整数,分别代表操作类型和操作所需的量。

    Output

    对于每一个0号操作,你须输出X到Y的路径上点权的Xor和。

    Sample Input

    3 3
    1
    2
    3
    1 1 2
    0 1 2
    0 1 1

    Sample Output

    3
    1

    HINT

    1<=N,M<=300000

    Source

    动态树


    不能再做水题了!!!

    跟上道题一模一样,只是xor和而已,xor满足结合律

    [update 2017-04-05]

    更新一下代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    #define lc t[x].ch[0]
    #define rc t[x].ch[1]
    #define pa t[x].fa
    typedef long long ll;
    const int N=3e5+5;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    namespace lct {
        struct meow{int ch[2], fa, rev, sum, w;} t[N];
        inline int wh(int x) {return t[pa].ch[1] == x;}
        inline int isr(int x) {return t[pa].ch[0] != x && t[pa].ch[1] != x;}
        inline void update(int x) {t[x].sum = t[lc].sum ^ t[rc].sum ^ t[x].w;}
        inline void rever(int x) {t[x].rev ^= 1; swap(lc, rc);}
        inline void pushdn(int x) {
            if(t[x].rev) {
                if(lc) rever(lc);
                if(rc) rever(rc);
                t[x].rev = 0;
            }
        }
        void pd(int x) {if(!isr(x)) pd(pa); pushdn(x);}
        inline void rotate(int x) {
            int f=t[x].fa, g=t[f].fa, c=wh(x);
            if(!isr(f)) t[g].ch[wh(f)]=x; t[x].fa=g;
            t[f].ch[c] = t[x].ch[c^1]; t[t[f].ch[c]].fa=f;
            t[x].ch[c^1] = f; t[f].fa=x;
            update(f); update(x);
        }
        inline void splay(int x) {
            pd(x);
            for(; !isr(x); rotate(x))
                if(!isr(pa)) rotate( wh(pa)==wh(x) ? pa : x );
        }
    
        inline void access(int x) {
            for(int y=0; x; y=x, x=pa) splay(x), rc=y, update(x);
        }
        inline void maker(int x) {
            access(x); splay(x); rever(x);
        }
        inline int findr(int x) {
            access(x); splay(x);
            while(lc) pushdn(x), x=lc; return x;
        }
        inline void link(int x, int y) {
            maker(x); t[x].fa=y;
        }
        inline void cut(int x, int y) {
            maker(x); access(y); splay(y);
            t[x].fa = t[y].ch[0] = 0; update(y);
        }
        inline void split(int x, int y) {
            maker(x); access(y); splay(y);
        }
    } using lct::findr;
    
    int n, Q, op, x, y;
    int main() {
        freopen("in","r",stdin);
        n=read(); Q=read();
        for(int i=1; i<=n; i++) lct::t[i].w = read();
        for(int i=1; i<=Q; i++) {
            op=read(); x=read(); y=read();
            if(op==0) lct::split(x, y), printf("%d
    ", lct::t[y].sum);
            if(op==1) if(findr(x) != findr(y)) lct::link(x, y);
            if(op==2) if(findr(x) == findr(y)) lct::cut(x, y);
            if(op==3) lct::t[x].w = y, lct::splay(x);
        }
    }
  • 相关阅读:
    97. Interleaving String (String; DP)
    140. Word Break II (String; DP,DFS)
    139. Word Break (String; DP)
    120. Triangle(Array; DP)
    132. Palindrome Partitioning II (String; DP)
    91. Decode Ways (Array; DP)
    45. Jump Game II (Array; Two-Pointers,Greedy)
    LeetCode Excel Sheet Column Number
    LeetCode Factorial Trailing Zeroes
    LeetCode SQL: Second Highest Salary
  • 原文地址:https://www.cnblogs.com/candy99/p/6274184.html
Copyright © 2020-2023  润新知