1. 程式人生 > >LCT教程

LCT教程

lct是一種動態樹,用來維護一些動態加邊刪邊的操作的東西.他主要用到幾個操作,其實這個演算法和樹鏈刨分有點像,但是不能用線段樹簡單維護,所以我們要用多棵平衡樹來維護樹上的一個個子樹,然後就進行一些很秀的操作.詳情見這個部落格:FlashHu

這個部落格講的是真的好,特別適合新手看,而且特別細節,(特別帶勁).現在我就可以上程式碼:

模板:

#include <iostream>
#include <cassert>
#include <cstdio>
#include <cmath>
#include <ctime>
#include 
<queue> #include <algorithm> #include <cstring> using namespace std; #define duke(i, a, n) for (register int i = a; i <= n; i++) #define lv(i, a, n) for (register int i = a; i >= n; i--) #define clean(a) memset(a, 0, sizeof(a)) const int INF = 1 << 30; typedef long
long ll; typedef double db; template <class T> void read(T &x) { char c; bool op = 0; while (c = getchar(), c < '0' || c > '9') if (c == '-') op = 1; x = c - '0'; while (c = getchar(), c >= '0' && c <= '9') x = x * 10 + c - '
0'; if (op) x = -x; } template <class T> void write(T x) { if (x < 0) putchar('-'), x = -x; if (x >= 10) write(x / 10); putchar('0' + x % 10); } const int N = 300009; struct node { int fa, ch[2], rev, v, s; } a[N]; int st[N]; #define O(a) cout << #a << " " << a << endl; int n, m; bool isroot(int x) { return !(a[a[x].fa].ch[0] == x || a[a[x].fa].ch[1] == x); } void pushr(int x) { swap(a[x].ch[0], a[x].ch[1]); a[x].rev ^= 1; } void push_down(int k) { if (a[k].rev) { if (a[k].ch[0]) pushr(a[k].ch[0]); if (a[k].ch[1]) pushr(a[k].ch[1]); a[k].rev ^= 1; } } void push_up(int x) { a[x].s = a[a[x].ch[0]].s ^ a[a[x].ch[1]].s ^ a[x].v; } void connect(int x, int fa, int son) { a[x].fa = fa; a[fa].ch[son] = x; } int iden(int x) { return a[a[x].fa].ch[0] == x ? 0 : 1; } void rotate(int x) { int y = a[x].fa; int mroot = a[y].fa; int mrootson = iden(y); int yson = iden(x); int b = a[x].ch[yson ^ 1]; if (!isroot(y)) { a[mroot].ch[mrootson] = x; } a[x].fa = mroot; connect(b, y, yson); connect(y, x, yson ^ 1); push_up(y); push_up(x); } void splay(int x) { int top = 0;int i; st[++top] = x; for (i = x; !isroot(i); i = a[i].fa) { st[++top] = a[i].fa; } for (int i = top; i >= 1; i--) { push_down(st[i]); } while (!isroot(x)) { int y = a[x].fa; if (isroot(y)) { rotate(x); } else if (iden(x) == iden(y)) { rotate(y); rotate(x); } else { rotate(x); rotate(x); } } push_up(x); } void access(int x) { int t = 0; while (x) { splay(x); a[x].ch[1] = t; push_up(x); t = x; x = a[x].fa; } } void make_root(int x) { access(x); splay(x); // a[a[x].ch[0]].rev ^= 1; // a[a[x].ch[1]].rev ^= 1; pushr(x); // swap(a[x].ch[0],a[x].ch[1]); // push_down(x); } void split(int x, int y) { // if (x <= n && y <= n) { make_root(x); access(y); splay(y); // } } int findroot(int x) { access(x); splay(x); push_down(x); while (a[x].ch[0]){ push_down(a[x].ch[0]); x = a[x].ch[0]; } return x; } void link(int x, int y) { make_root(x); int t = findroot(y); assert(t); if ( t != x) a[x].fa = y; } void cut(int x, int y) { make_root(x); int t = findroot(y); assert(t); if (t == x && a[x].fa == y && !a[x].ch[1]) { a[x].fa = a[y].ch[0] = 0; push_up(y); } } int main() { // freopen("in.in","r",stdin); int x, y, typ; read(n); read(m); duke(i, 1, n) { read(a[i].v); push_up(i); } int oup = 0; duke(mi,1,m){ read(typ); read(x); read(y); if (typ == 0) { split(x, y); printf("%d\n", a[y].s); ++oup; } else if (typ == 1) { link(x, y); } else if (typ == 2) { cut(x, y); } else { splay(x); a[x].v = y; } // cout<<a[1].ch[0]<<" "<<a[1].ch[1]<<" "<<a[1].fa<<" "<<a[1].v<<" "<<a[1].s<<endl; } return 0; }

魔法森林:

// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(register int i = a;i <= n;i++)
#define lv(i,a,n) for(register int i = a;i >= n;i--)
#define clean(a) memset(a,0,sizeof(a))
const int INF = 1 << 30;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
    char c;
    bool op = 0;
    while(c = getchar(), c < '0' || c > '9')
        if(c == '-') op = 1;
    x = c - '0';
    while(c = getchar(), c >= '0' && c <= '9')
        x = x * 10 + c - '0';
    if(op) x = -x;
}
template <class T>
void write(T x)
{
    if(x < 0) putchar('-'), x = -x;
    if(x >= 10) write(x / 10);
    putchar('0' + x % 10);
}
#define min2(x,y) if(x>y)x=y;
const int N = 2e5 + 5;
const int P = 131072;
struct node
{
    int fa,ch[2],rev,v,mx;
}a[N];
int st[N],n,m;
struct edge
{
    int u,v,a,b;
    bool operator < (const edge &oth) const
    {
        return a < oth.a;
    }
    void getin()
    {
        read(u);read(v);
        read(a);read(b);
        u |= P;v |= P;
    }
}e[2 * N];
bool isroot(int x)
{
    return a[a[x].fa].ch[0] != x && a[a[x].fa].ch[1] != x;
}
void pushr(int x)
{
    swap(a[x].ch[0],a[x].ch[1]);
    a[x].rev ^= 1;
}
void push_down(int x)
{
    if(a[x].rev)
    {
//        if(a[a[x].ch[0]].rev) pushr(a[x].ch[0]);
//        if(a[a[x].ch[1]].rev) pushr(a[x].ch[1]);
        swap(a[x].ch[0],a[x].ch[1]);
        a[a[x].ch[0]].rev ^= 1;
        a[a[x].ch[1]].rev ^= 1;
        a[x].rev ^= 1;
    }
}
void push_up(int x)
{
    a[x].mx = x;
    if(e[a[x].mx].b < e[a[a[x].ch[0]].mx].b) a[x].mx = a[a[x].ch[0]].mx;
    if(e[a[x].mx].b < e[a[a[x].ch[1]].mx].b) a[x].mx = a[a[x].ch[1]].mx;
}
int iden(int x)
{
    return a[a[x].fa].ch[0] == x ? 0 : 1;
}
void connect(int x,int fa,int son)
{
    a[x].fa = fa;
    a[fa].ch[son] = x;
}
void rotate(int x)
{
    int y = a[x].fa;
    int mroot = a[y].fa;
    int mrootson = iden(y);
    int yson = iden(x);
    int b = a[x].ch[yson ^ 1];
    if(!isroot(y))
    {
        a[mroot].ch[mrootson] = x;
    }
    a[x].fa = mroot;
    connect(y,x,yson ^ 1);
    connect(b,y,yson);
    push_up(y);
//    update(x);
}
void splay(int x)
{
    int top = 0,i;
    st[++top] = x;
    for(i = x;!isroot(i);i = a[i].fa)
    {
        st[++top] = a[i].fa;
    }
    push_down(a[i].fa);
    for(int i = top;i;i--)
    {
        push_down(st[i]);
    }
    while(!isroot(x))
    {
        int y = a[x].fa;
        if(isroot(y)) rotate(x);
        else if(iden(x) == iden(y))
        {
            rotate(y);rotate(x);
        }
        else
        {
            rotate(x);rotate(x);
        }
    }
    push_up(x);
}
void access(int x)
{
    int t = 0;
    while(x)
    {
        splay(x);
        a[x].ch[1] = t;
        push_up(x);
        t = x;
        x = a[x].fa;
    }
}
void makeroot(int x)
{
    access(x);
    splay(x);
    a[x].rev ^= 1; 
}
int findroot(int x)
{
    access(x);
    splay(x);
    while(a[x].ch[0])
    x = a[x].ch[0];
    return x;
}
void link(int x)
{
    int y = e[x].u,z = e[x].v;
    makeroot(z);
    a[a[z].fa = x].fa = y;
//    a[x].fa = y;
}
void cut(int x)
{
    access(e[x].v);
    splay(x);
    a[x].ch[0] = a[x].ch[1] = a[a[x].ch[0]].fa = a[a[x].ch[1]].fa = 0;
    push_up(x);
}
int main()
{
//    freopen("2387.in","r",stdin);
    int ans = INF;
    read(n);read(m);
    duke(i,1,m)
    {
        e[i].getin();
    }
    sort(e + 1,e + m + 1);
    int y,z;
    duke(i,1,m)
    {
        if((y = e[i].u) == (z = e[i].v)) continue;
        makeroot(y);
        if(y != findroot(z)) link(i);
        else if(e[i].b < e[a[z].mx].b) 
        {
            cut(a[z].mx);
            link(i);
        }
        makeroot(1 | P);
        if((1 | P) == findroot(n | P))
        ans = min(ans,e[i].a + e[a[n | P].mx].b);
    }
    printf("%d\n",ans == INF ? -1 : ans);
    return 0;
}

彈飛綿羊:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<algorithm>
#include<vector>
#include<complex>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(int i = a;i <= n;i++)
#define lv(i,a,n) for(int i = a;i >= n;i--)
#define clean(a) memset(a,0,sizeof(a))
#define mp make_pair
#define cp complex<db>
#define enter puts("")
const long long INF = 1LL << 60;
const double eps = 1e-8;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
    char c;
    bool op = 0;
    while(c = getchar(), c < '0' || c > '9')
        if(c == '-') op = 1;
    x = c - '0';
    while(c = getchar(), c >= '0' && c <= '9')
        x = x * 10 + c - '0';
    if(op) x = -x;
}
template <class T>
void write(T x)
{
    if(x < 0) putchar('-'), x = -x;
    if(x >= 10) write(x / 10);
    putchar('0' + x % 10);
}
struct node
{
    int ch[2],siz,fa;
}a[1000005];
int n,m;
int iden(int x)
{
    return a[a[x].fa].ch[0] == x ? 0 : 1;
}
void connect(int x,int fa,int son)
{
    a[x].fa = fa;
    a[fa].ch[son] = x;
}
bool isroot(int x)
{
    return a[a[x].fa].ch[0] != x && a[a[x].fa].ch[1] != x;
}
void push_up(int x)
{
    a[x].siz = a[a[x].ch[0]].siz + a[a[x].ch[1]].siz + 1;
}
/*void pushr(int x)
{
    swap(a[x].ch[0],a[x].ch[1]);
    a[x].rev ^= 1;
}
void push_down(int x)
{
    if(a[x].rev)
    {
        if(a[x].ch[0]) pushr(a[x].ch[0]);
        if(a[x].ch[1]) pushr(a[x].ch[1]);
        a[x].rev ^= 1;
    }
}*/
void rotate(int x)
{
    int y = a[x].fa;
    int mroot = a[y].fa;
    int mrootson = iden(y);
    int yson =iden(x);
    int b = a[x].ch[yson ^ 1];
    if(!isroot(y))
    {
        a[mroot].ch[mrootson] = x;
    }
    a[x].fa = mroot;
    connect(b,y,yson);
    connect(y,x,yson ^ 1);
    push_up(y);
}
/*inline bool isroot(int x){
    return a[a[x].fa].ch[0]==x||a[a[x].fa].ch[1]==x;
}
void rotate(int x){
    int y=a[x].fa,z=a[y].fa,k=a[y].ch[1]==x,w=a[x].ch[!k];
    if(isroot(y))a[z].ch[a[z].ch[1]==y] = x;a[x].ch[!k]=y;a[y].ch[k]=w;
    if(w)a[w].fa=y;a[y].fa=x;a[x].fa=z;
    push_up(y);
}*/
void splay(int x)
{
    while(!isroot(x))
    {
        int y = a[x].fa;
        if(isroot(y)) rotate(x);
        else if(iden(x) == iden(y))
        {
            rotate(y);rotate(x);
        }
        else
        {
            rotate(x);rotate(x);
        }
    }
    push_up(x);
}
/*void splay(int x){
    int y,z;
    while(isroot(x)){
        y=a[x].fa;z=a[y].fa;
        cout<<x<<endl;
        if(isroot(y))
            rotate((a[y].ch[0]==x)^(a[z].ch[0]==y)?y:x);
        rotate(x);
    }
    push_up(x);
}*/
void access(int x)
{
    int t = 0;
    while(x)
    {
        splay(x);
        a[x].ch[1] = t;
        t = x;
        push_up(x);
        x = a[x].fa;
    }
}
int ch,j,k;
int main()
{
    // freopen("3203.in","r",stdin);
    read(n);
    duke(i,1,n)
    {
        a[i].siz = 1;
        read(k);
        if(i + k <= n)
        a[i].fa = i + k;
    }
    read(m);
    while(m--)
    {
        read(ch);
        if(ch == 1)
        {
            read(j);j++;
            access(j);splay(j);
            printf("%d\n",a[j].siz);
        }
        else
        {
            read(j);read(k); ++j;
            access(j);splay(j);
            a[j].ch[0] = a[a[j].ch[0]].fa = 0;
            if(j + k <= n) a[j].fa = j + k;
            push_up(j);
        }
    }
    return 0;
}
/*int main()
{
    freopen("3203.in","r",stdin);
    register char ch;
    int n,m,j,k;
    read(n);
    for(j=1;j<=n;++j){
        a[j].siz=1;
        read(k);
        if(j+k<=n)a[j].fa=j+k;//如果彈飛了就不連邊
    }
    read(m);
    int op = 0;
    while(m--){
        read(op);
        if(op&1){
            read(j);++j;
            access(j);splay(j);//直接查詢
            printf("%d\n",a[j].siz);
        }
        else{
            read(j);read(k);++j;
            access(j);splay(j);
            a[j].ch[0]=a[a[j].ch[0]].fa=0;//直接斷邊
            if(j+k<=n)a[j].fa=j+k;//直接連邊
            push_
            up(j);
        }
    }
    return 0;
}*/

洞穴勘測:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(register int i = a;i <= n;i++)
#define lv(i,a,n) for(register int i = a;i >= n;i--)
#define clean(a) memset(a,0,sizeof(a))
const int INF = 1 << 30;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
    char c;
    bool op = 0;
    while(c = getchar(), c < '0' || c > '9')
        if(c == '-') op = 1;
    x = c - '0';
    while(c = getchar(), c >= '0' && c <= '9')
        x = x * 10 + c - '0';
    if(op) x = -x;
}
template <class T>
void write(T x)
{
    if(x < 0) putchar('-'), x = -x;
    if(x >= 10) write(x / 10);
    putchar('0' + x % 10);
}
struct node
{
    int fa,ch[2],rev;
}a[10005];
int n,m,st[10005];
bool isroot(int x)
{
    return a[a[x].fa].ch[0] != x && a[a[x].fa].ch[1] != x;
}
void push_down(int k)
{
    if(a[k].rev)
    {
        int l = a[k].ch[0];
        int r = a[k].ch[1];
        a[k].rev ^= 1;
        a[l].rev ^= 1;
        a[r].rev ^= 1;
        swap(a[k].ch[0],a[k].ch[1]);
    }
}
int iden(int x)
{
    return a[a[x].fa].ch[0] == x ? 0 : 1;
}
void connect(int x,int f,int son)
{
    a[x].fa = f;
    a[f].ch[son] = x;
}
void rotate(int x)
{
    int y = a[x].fa;
    int mroot = a[y].fa;
    int mrootson = iden(y);
    int yson = iden(x);
    int b = a[x].ch[yson ^ 1];
    if(!isroot(y))
    {
        a[mroot].ch[mrootson] = x;
    }
    a[x].fa = mroot;
    connect(b,y,yson);
    connect(y,x,yson ^ 1);
}
void splay(int x)
{
    int top = 0;
    st[++top] = x;
    for(int i = x;!isroot(i);i = a[i].fa)
    {
        st[++top] = a[i].fa;
        // cout<<"gg"<<endl;
    }
    // cout<<"out"<<endl;
    for(int i = top;i;i--)
    push_down(st[i]);
    while(!isroot(x))
    {
        int y = a[x].fa;
        if(isroot(y)) rotate(x);
        else if(iden(x) == iden(y))
        {
            rotate(y);rotate(x);
        }
        else
        {
            rotate(x);rotate(x);
        }
        // cout<<"233"<<endl;
    }
}
void access(int x)
{
    int t = 0;
    while(x)
    {
        splay(x);
        a[x].ch[1] = t;
        t = x;
        x = a[x].fa;
    }
}
void rever(int x)
{
    access(x);
    splay(x);
    a[x].rev ^= 1;
}
void link(int x,int y)
{
    rever(x);a[x].fa = y;
    splay(x);
    // cout<<x<<" "<<y<<endl;
}
void cut(int x,int y)
{
    rever(x);
    access(y);
    splay(y);
    a[y].ch[0] = a[x].fa = 0;
}
int find(int x)
{
//    cout<<x<<endl;
    access(x);//cout<<"yes"<<endl;
    splay(x);
    int y = x;
    //cout<<"!!!"<<y<<endl;
    while(a[y].ch[0])
    y = a[y].ch[0];
    // cout<<y<<endl;
    return y;
}
int main()
{
    // freopen("2147.in","r",stdin);
    char ch[10];
    int x,y;
    read(n);read(m);
    duke(i,1,m)
    {
        scanf("%s",ch);
        read(x);read(y);
        if(ch[0] == 'C') link(x,y);
        else if(ch[0] == 'D') cut(x,y);
        else
        {
            if(find(x) == find(y)) printf("Yes\n");
            else
            printf("No\n");
        }
    }
    return 0;
}