MnZn 求助 LCT
  • 板块学术版
  • 楼主Hoks
  • 当前回复2
  • 已保存回复2
  • 发布时间2024/4/29 14:15
  • 上次更新2024/4/29 18:52:24
查看原帖
MnZn 求助 LCT
551100
Hoks楼主2024/4/29 14:15

知周所众的是,P10075 [GDKOI2024 普及组] 切割 和 P5227 [AHOI2013] 连通图 是重题(样例都一样)。

但是唯一不同的是,前者的**出题人造的数据里有重边。

不懂就问,LCT 处理此问题时有重边是否会挂,为何会出现 WA+TLE 的情况。

代码如下:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10,INF=0x3f3f3f3f3f3f3f3f;
struct edge{int x,y,w;}e[N];
struct query{int op,x,t;}q[N];
int n,m,k,tot,cnt,cur[N],st[10];
namespace Fast_IO
{
    static char buf[1000000],*paa=buf,*pd=buf,out[10000000];int length=0;
    #define getchar() paa==pd&&(pd=(paa=buf)+fread(buf,1,1000000,stdin),paa==pd)?EOF:*paa++
    inline int read()
    {
        int x(0),t(1);char fc(getchar());
        while(!isdigit(fc)){if(fc=='-') t=-1;fc=getchar();}
        while(isdigit(fc)) x=(x<<1)+(x<<3)+(fc^48),fc=getchar();
        return x*t;
    }
    inline void flush(){fwrite(out,1,length,stdout);length=0;}
    inline void put(char c){if(length==9999999) flush();out[length++]=c;}
    inline void put(string s){for(char c:s) put(c);}
    inline void print(int x)
    {
        if(x<0) put('-'),x=-x;
        if(x>9) print(x/10);
        put(x%10+'0');
    }
    inline bool chk(char c) { return !(c>='a'&&c<='z'||c>='A'&&c<='Z'||c>='0'&&c<='9'); }
    inline bool ck(char c) { return c!='\n'&&c!='\r'&&c!=-1&&c!=' '; }
    inline void rd(char s[],int&n)
    {
        s[++n]=getchar();
        while(chk(s[n])) s[n]=getchar();
        while(ck(s[n])) s[++n]=getchar();
        n--;
    }
}
using namespace Fast_IO;
struct LCT
{
    #define ls son[x][0]
    #define rs son[x][1]
    int f[N],s[N],ss[N],t[N],son[N][2],st[N],w[N],r[N],mn[N];
    bool ntrt(int x){return son[f[x]][1]==x||son[f[x]][0]==x;}
    void pushup(int x)
    {
        (x>n)&&(s[x]=x);ss[x]=ss[ls]+ss[rs]+t[x]+(x<=n);
        if(w[x]>=w[s[ls]]) s[x]=s[ls];
        if(w[s[x]]>=w[s[rs]]) s[x]=s[rs];
    }
    void pushson(int x){swap(ls,rs),r[x]^=1;}
    void pushdown(int x)
    {
        if(r[x])
        {
            if(ls) pushson(ls);
            if(rs) pushson(rs);
            r[x]=0;
        }
    }
    void rotate(int x)
    {
        int y=f[x],z=f[y],k=(son[y][1]==x),w=son[x][!k];
        if(ntrt(y)) son[z][son[z][1]==y]=x;son[x][!k]=y;son[y][k]=w;
        if(w) f[w]=y;f[y]=x;f[x]=z;pushup(y);
    }
    void Splay(int x)
    {
        int y=x,tot=0;st[++tot]=y;
        while(ntrt(y)) st[++tot]=y=f[y];
        while(tot) pushdown(st[tot--]);
        while(ntrt(x))
        {
            y=f[x];int z=f[y];
            if(ntrt(y)) rotate((son[y][0]==x)^(son[z][0]==y)?x:y);
            rotate(x);
        }
        pushup(x);
    }
    void access(int x){for(int y=0;x;x=f[y=x]) Splay(x),t[x]+=ss[rs],t[x]-=ss[rs=y],pushup(x);}
    void makert(int x){access(x);Splay(x);pushson(x);}
    int findrt(int x)
    {
        access(x);Splay(x);
        while(ls) pushdown(x),x=ls;
        Splay(x);return x;
    }
    void split(int x,int y){makert(y);access(x);Splay(x);}
    void link(int x,int y){split(x,y);f[y]=x,t[x]+=ss[y];}
    void cut(int x,int y){split(x,y);f[y]=ls=0,pushup(x);}
    #undef ls
    #undef rs
}lct;
signed main()
{
    n=read(),tot=m=read();
    for(int i=1;i<=m;i++) e[i].x=read(),e[i].y=read(),cur[i]=i,q[++cnt]={1,i,0};
    k=read();for(int i=0;i<=n;i++) lct.w[i]=INF;
    for(int i=1,x,T,top=0;i<=k;i++)
    {
        T=read();
        for(int j=1;j<=T;j++)
        {
            x=read();e[cur[x]].w=i-1;lct.w[cur[x]+n]=i-1;
            q[++cnt]={2,cur[x],i};e[++tot]=e[cur[x]];
            e[tot].w=0,cur[x]=tot;st[++top]=cur[x];
        }q[++cnt]={0};
        if(i!=k) while(top) q[++cnt]={1,st[top--],i};
    }
    for(int i=1;i<=m;i++) if(!e[cur[i]].w) e[cur[i]].w=k,lct.w[cur[i]+n]=k;
    tot+=n;for(int i=1;i<=tot;i++) lct.ss[i]=1;
    for(int i=1,j,x,y,w;i<=cnt;i++)
    {
        if(!q[i].op){lct.access(1),lct.Splay(1),put(lct.ss[1]==n?"ymqOAO\n":"Bob\n");continue;}
        j=q[i].x;x=e[j].x,y=e[j].y,w=e[j].w;lct.makert(x);
        if(q[i].op==1)
        {
            if(lct.findrt(y)==x)
            {
                int ww=lct.s[x];if(lct.w[ww]>=w) continue;
                lct.cut(e[ww-n].x,ww),lct.cut(e[ww-n].y,ww);
            }
            lct.link(x,j+n),lct.link(y,j+n);
        }
        else
            if(lct.findrt(y)==x)
            {
                lct.pushup(j+n);
                if(!lct.f[j+n]&&!lct.ss[j+n]) continue;
                lct.cut(x,j+n),lct.cut(y,j+n);
            }
    }
    genshin:;flush();return 0;
}
2024/4/29 14:15
加载中...