一、例题①:P4320 道路相遇
可能是因为把树封装了,倍增怎么写都超时。
不过倍增确实慢,树剖快好多。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<queue>
#define ll long long
#define pr make_pair
#define pb push_back
//#define lc (p<<1)
//#define rc (p<<1|1)
using namespace std;


char buffer[100001],*S,*T;
inline char Get_Char()
{
    if (S==T)
    {
        T=(S=buffer)+fread(buffer,1,100001,stdin);
        if (S==T) return EOF;
    }
    return *S++;
}
inline int read()
{
    char c;int re=0;
    for(c=Get_Char();c<'0'||c>'9';c=Get_Char());
    while(c>='0'&&c<='9') re=re*10+(c-'0'),c=Get_Char();
    return re;
}




const int inf=0x3f3f3f3f;
const ll lnf=0x3f3f3f3f3f3f3f3f;
const double dnf=1e15;
const int mod=1e9+7;
const int maxn=4000100;
int dfn[maxn],low[maxn],st[maxn];
int cnt=0,tp=0,n,m,q,cntf;
int d[maxn],f[maxn],son[maxn],si[maxn];
int id[maxn],top[maxn];

struct Tree
{
    int head[maxn],ver[maxn],nt[maxn];
    int tot=1;
    void add(int x,int y)
    {
        ver[++tot]=y,nt[tot]=head[x],head[x]=tot;
    }
}yy,yf;


void dfs(int x)
{
    dfn[x]=low[x]=++cnt;
    st[++tp]=x;

    for(int i=yy.head[x];i;i=yy.nt[i])
    {
        int y=yy.ver[i];
        if(!dfn[y])
        {
            dfs(y);
            low[x]=min(low[x],low[y]);
            if(low[y]>=dfn[x])
            {
                cntf++;
                yf.add(cntf,x);
                yf.add(x,cntf);
                int z;
                do
                {
                    z=st[tp--];
                    yf.add(cntf,z);
                    yf.add(z,cntf);
                }while(z!=y);
            }
        }
        else low[x]=min(low[x],dfn[y]);
    }

}

void dfs1(int x,int fa)
{
    int max_son=0;
    si[x]=1;
    for(int i=yf.head[x];i;i=yf.nt[i])
    {
        int y=yf.ver[i];
        if(y==fa) continue;
        d[y]=d[x]+1;
        f[y]=x;
        dfs1(y,x);
        si[x]+=si[y];
        if(si[y]>max_son) max_son=si[y],son[x]=y;
    }
}

void dfs2(int x,int t)
{
    top[x]=t;
    id[x]=++cnt;
    if(!son[x]) return ;
    dfs2(son[x],t);
    for(int i=yf.head[x];i;i=yf.nt[i])
    {
        int y=yf.ver[i];
        if(y!=son[x]&&y!=f[x])
            dfs2(y,y);
    }
}

int lca(int x,int y)
{
    while(top[x]!=top[y])
    {
        if(d[top[x]]<d[top[y]]) swap(x,y);
        x=f[top[x]];
    }
    return id[x]>id[y]?y:x;
}


int main(void)
{

    n=read(),m=read();

    int x,y;
    for(int i=1;i<=m;i++)
    {
        x=read(),y=read();
        yy.add(x,y);
        yy.add(y,x);
    }

    cntf=n;
    dfs(1);

    dfs1(1,0);
    dfs2(1,1);

    q=read();
    for(int i=1;i<=q;i++)
    {
        x=read(),y=read();
        int lc=lca(x,y);
        printf("%d\n",(d[x]+d[y]-2*d[lc])/2+1);
    }

    return 0;
}


二、例题②:P4606 [SDOI2018]战略游戏

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<queue>
#define ll long long
#define pr make_pair
#define pb push_back
//#define lc (p<<1)
//#define rc (p<<1|1)
using namespace std;


char buffer[100001],*S,*T;
inline char Get_Char()
{
    if (S==T)
    {
        T=(S=buffer)+fread(buffer,1,100001,stdin);
        if (S==T) return EOF;
    }
    return *S++;
}
inline int read()
{
    char c;int re=0;
    for(c=Get_Char();c<'0'||c>'9';c=Get_Char());
    while(c>='0'&&c<='9') re=re*10+(c-'0'),c=Get_Char();
    return re;
}




const int inf=0x3f3f3f3f;
const ll lnf=0x3f3f3f3f3f3f3f3f;
const double dnf=1e15;
const int mod=1e9+7;
const int maxn=400100;
int dfn[maxn],low[maxn],st[maxn],s[maxn];
int cnt=0,tp=0,n,m,q,cntf;
int d[maxn],f[maxn],son[maxn],si[maxn];
int id[maxn],top[maxn],dis[maxn];

struct Tree
{
    int head[maxn],ver[maxn],nt[maxn];
    int tot;
    void add(int x,int y)
    {
        ver[++tot]=y,nt[tot]=head[x],head[x]=tot;
    }
}yy,yf;


void init(int n)
{
    for(int i=1;i<=n;i++)
        dfn[i]=son[i]=yy.head[i]=yf.head[i]=0;
    yy.tot=yf.tot=1;
    cnt=tp=0;
}

void dfs(int x)
{
    dfn[x]=low[x]=++cnt;
    st[++tp]=x;

    for(int i=yy.head[x];i;i=yy.nt[i])
    {
        int y=yy.ver[i];
        if(!dfn[y])
        {
            dfs(y);
            low[x]=min(low[x],low[y]);
            if(low[y]>=dfn[x])
            {
                cntf++;
                yf.add(cntf,x);
                yf.add(x,cntf);
                int z;
                do
                {
                    z=st[tp--];
                    yf.add(cntf,z);
                    yf.add(z,cntf);
                }while(z!=y);
            }
        }
        else low[x]=min(low[x],dfn[y]);
    }

}

void dfs1(int x,int fa)
{
    int max_son=0;
    si[x]=1;
    for(int i=yf.head[x];i;i=yf.nt[i])
    {
        int y=yf.ver[i];
        if(y==fa) continue;
        d[y]=d[x]+1;
        dis[y]=dis[x]+(y<=n);
        f[y]=x;
        dfs1(y,x);
        si[x]+=si[y];
        if(si[y]>max_son) max_son=si[y],son[x]=y;
    }
}

void dfs2(int x,int t)
{
    top[x]=t;
    id[x]=++cnt;
    if(!son[x]) return ;
    dfs2(son[x],t);
    for(int i=yf.head[x];i;i=yf.nt[i])
    {
        int y=yf.ver[i];
        if(y!=son[x]&&y!=f[x])
            dfs2(y,y);
    }
}

bool cmp(const int a,const int b)
{
    return id[a]<id[b];
}

int lca(int x,int y)
{
    while(top[x]!=top[y])
    {
        if(d[top[x]]<d[top[y]]) swap(x,y);
        x=f[top[x]];
    }
    return id[x]>id[y]?y:x;
}


int main(void)
{

    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        init(n*2);

        int x,y;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            yy.add(x,y);
            yy.add(y,x);
        }

        cntf=n;
        dfs(1);

        cnt=0;
        dfs1(1,0);
        dfs2(1,1);

        scanf("%d",&q);
        for(int i=1;i<=q;i++)
        {
            int cnts;
            scanf("%d",&cnts);
            for(int i=1;i<=cnts;i++)
                scanf("%d",&s[i]);
            sort(s+1,s+cnts+1,cmp);
            s[cnts+1]=s[1];
            int ans=0;
            for(int i=1;i<=cnts;i++)
                ans+=dis[s[i]]+dis[s[i+1]]-2*dis[lca(s[i],s[i+1])];
            ans=ans/2-cnts+(lca(s[1],s[cnts])<=n);
            printf("%d\n",ans);
        }
    }
    return 0;
}

三、例③:【CF Round #278】Tourists

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<queue>
#define ll long long
#define pr make_pair
#define pb push_back
#define lc (cnt<<1)
#define rc (cnt<<1|1)
using namespace std;


char buffer[100001],*S,*T;
inline char Get_Char()
{
    if (S==T)
    {
        T=(S=buffer)+fread(buffer,1,100001,stdin);
        if (S==T) return EOF;
    }
    return *S++;
}
inline int read()
{
    char c;int re=0;
    for(c=Get_Char();c<'0'||c>'9';c=Get_Char());
    while(c>='0'&&c<='9') re=re*10+(c-'0'),c=Get_Char();
    return re;
}


const int inf=0x3f3f3f3f;
const ll lnf=0x3f3f3f3f3f3f3f3f;
const double dnf=1e15;
const int mod=1e9+7;
const int maxn=400100;

int dfn[maxn],low[maxn],st[maxn],val[maxn];
int cnt1=0,cnt2=0,tp=0,n,m,q,cntf;
int d[maxn],f[maxn],son[maxn],si[maxn];
int rk[maxn],id[maxn],top[maxn];
multiset<int>se[maxn];


struct Tree
{
    int head[maxn],ver[maxn],nt[maxn];
    int tot;
    void add(int x,int y)
    {
        ver[++tot]=y,nt[tot]=head[x],head[x]=tot;
    }
}yy,yf;



void dfs(int x)
{
    dfn[x]=low[x]=++cnt1;
    st[++tp]=x;

    for(int i=yy.head[x];i;i=yy.nt[i])
    {
        int y=yy.ver[i];
        if(!dfn[y])
        {
            dfs(y);
            low[x]=min(low[x],low[y]);
            if(low[y]>=dfn[x])
            {
                cntf++;
                yf.add(cntf,x);
                yf.add(x,cntf);
                int z;
                do
                {
                    z=st[tp--];
                    yf.add(cntf,z);
                    yf.add(z,cntf);
                }while(z!=y);
            }
        }
        else low[x]=min(low[x],dfn[y]);
    }

}

void dfs1(int x,int fa)
{
    int max_son=0;
    si[x]=1;
    if(fa) se[fa].insert(val[x]);
    for(int i=yf.head[x];i;i=yf.nt[i])
    {
        int y=yf.ver[i];
        if(y==fa) continue;
        d[y]=d[x]+1;
        f[y]=x;
        dfs1(y,x);
        si[x]+=si[y];
        if(si[y]>max_son) max_son=si[y],son[x]=y;
    }
}

void dfs2(int x,int t)
{
    top[x]=t;
    id[x]=++cnt2;
    rk[cnt2]=x;
    if(!son[x]) return ;
    dfs2(son[x],t);
    for(int i=yf.head[x];i;i=yf.nt[i])
    {
        int y=yf.ver[i];
        if(y!=son[x]&&y!=f[x])
            dfs2(y,y);
    }
}

struct node
{
    int l,r;
    int val;
}t[maxn<<2];

void pushup(int cnt)
{
    t[cnt].val=min(t[lc].val,t[rc].val);
}

void build(int l,int r,int cnt)
{
    t[cnt].l=l,t[cnt].r=r;
    if(l==r)
    {
        t[cnt].val=(rk[l]<=n?val[rk[l]]:*(se[rk[l]].begin()));
        return ;
    }
    int mid=(l+r)>>1;
    build(l,mid,lc);
    build(mid+1,r,rc);
    pushup(cnt);
}

void change(int pos,int cnt,int val)
{
    if(t[cnt].l==t[cnt].r)
    {
        t[cnt].val=val;
        return ;
    }
    if(pos<=t[lc].r) change(pos,lc,val);
    else change(pos,rc,val);
    pushup(cnt);
}

int ask(int l,int r,int cnt)
{
    if(l<=t[cnt].l&&t[cnt].r<=r)
        return t[cnt].val;
    int minn=inf;
    if(l<=t[lc].r) minn=min(minn,ask(l,r,lc));
    if(r>=t[rc].l) minn=min(minn,ask(l,r,rc));
    return minn;
}

void change(int x,int now)
{
    if(f[x])
    {
        se[f[x]].erase(se[f[x]].find(val[x]));
        se[f[x]].insert(now);
        change(id[f[x]],1,*se[f[x]].begin());
    }
    val[x]=now;
    change(id[x],1,now);
}

int ask(int x,int y)
{
    int minn=inf;
    while(top[x]!=top[y])
    {
        if(d[top[x]]<d[top[y]]) swap(x,y);
        minn=min(minn,ask(id[top[x]],id[x],1));
        x=f[top[x]];
    }
    if(id[x]>id[y]) swap(x,y);
    minn=min(minn,ask(id[x],id[y],1));
    if(x>n) minn=min(minn,val[f[x]]);
    return minn;
}

int main(void)
{


    scanf("%d%d%d",&n,&m,&q);
    for(int i=1;i<=n;i++)
        scanf("%d",&val[i]);
    int x,y;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        yy.add(x,y);
        yy.add(y,x);
    }

    cntf=n;
    dfs(1);

    dfs1(1,0);
    dfs2(1,1);
    build(1,cntf,1);

    char op[10];
    for(int i=1;i<=q;i++)
    {
        scanf("%s%d%d",op,&x,&y);
        if(op[0]=='A')
            printf("%d\n",ask(x,y));
        else change(x,y);
    }
    return 0;
}