zoukankan      html  css  js  c++  java
  • UOJ14 UER #1 DZY Loves Graph(最小生成树+并查集)

      显然可以用可持久化并查集实现。考虑更简单的做法。如果没有撤销操作,用带撤销并查集暴力模拟即可,复杂度显然可以均摊。加上撤销操作,删除操作的复杂度不再能均摊,但注意到我们在删除时就可以知道他会不会被撤销,所以遇到一个要被撤销的删除操作时,直接求出去掉k条边后的MST即可。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define N 300010
    #define M 500010
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int n,m,fa[N],size[N],e[M],cnt,top;
    char qwerty[10];
    ll ans;
    struct data{int op,x,y;
    }q[M];
    struct data2{int x,fa,s,i;ll sum;
    }stk[N<<1];
    int find(int x){return fa[x]==x?x:find(fa[x]);}
    int merge(int x,int y,int i)
    {
    	x=find(x),y=find(y);
    	if (x==y) return 0;
    	if (size[x]<size[y]) swap(x,y);
    	top++;stk[top].x=x;stk[top].fa=fa[x];stk[top].s=size[x];stk[top].i=i;stk[top].sum=stk[top-1].sum+i;
    	top++;stk[top].x=y;stk[top].fa=fa[y];stk[top].s=size[y];stk[top].i=i;stk[top].sum=stk[top-1].sum+i;
    	size[x]+=size[y],fa[y]=x;
    	return i;
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    	const char LL[]="%I64d
    ";
    #else
    	const char LL[]="%lld
    ";
    #endif
    	n=read(),m=read();
    	for (int i=1;i<=m;i++)
    	{
    		char c=getc();
    		if (c=='A') q[i].op=0,q[i].x=read(),q[i].y=read();
    		if (c=='D') q[i].op=1,q[i].x=read();
    		if (c=='R') q[i].op=2,cin>>qwerty;
    	}
    	for (int i=1;i<=n;i++) fa[i]=i,size[i]=1;
    	for (int i=1;i<=m;i++)
    	{
    		if (q[i].op==0) ans+=merge(q[i].x,q[i].y,i),e[++cnt]=i;
    		if (q[i].op==1)
    		{
    			int l=1,r=top,u=0;
    			while (l<=r)
    			{
    				int mid=l+r>>1;
    				if (stk[mid].i<=e[cnt-q[i].x]) u=mid,l=mid+1;
    				else r=mid-1;
    			}
    			ans=stk[u].sum>>1;
    			if (q[i+1].op!=2)
    			{
    				cnt-=q[i].x;
    				while (stk[top].i>e[cnt]) fa[stk[top].x]=stk[top].fa,size[stk[top].x]=stk[top].s,top--;
    			}
    		}
    		if (q[i].op==2)
    		{
    			if (q[i-1].op==0)
    			{
    				int x=0;
    				while (stk[top].i==i-1) fa[stk[top].x]=stk[top].fa,size[stk[top].x]=stk[top].s,x+=stk[top].i,top--;
    				ans-=x>>1;cnt--;
    			}
    			else ans=stk[top].sum/2;
    		}
    		if (top==(n-1<<1)&&ans==stk[top].sum/2) printf(LL,ans);
    		else printf("0
    ");
    		//for (int j=1;j<=cnt;j++) cout<<e[j]<<' ';cout<<endl;
    		//for (int j=2;j<=top;j+=2) cout<<stk[j].i<<' '<<stk[j].sum/2<<endl;
    		//cout<<endl;
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    综合日语第一册第十课
    综合日语第一册第九课
    荒木毬菜 小情歌日文版
    c# 匿名函数
    字典取KEY,占位符,延迟刷新
    flash GC
    自定义滤镜 ColorMatrixFilter
    sql join
    NSLog Release
    Windows 运行中的命令
  • 原文地址:https://www.cnblogs.com/Gloid/p/10738431.html
Copyright © 2011-2022 走看看