• bzoj 3514 Codechef MARCH14 GERALD07加强版


    bzoj

    题目要的连通块个数可以表示为点数(-)所有生成树上的边数.考虑这个生成树边数,我们维护编号最大生成树,按照编号加入边,然后如果加的时候会成环就把环上编号最小的边挤掉,并且当前的第(i)条边的前驱边(pre_i)为刚才被挤掉的第(j)条边,如果没有前驱边就是0

    然后对于一个询问,我们只把使得联连通块个数减少的边放在生成树上,也就是如果区间([l,r])中同时存在(i)(pre_i),就不统计(i)的贡献,那么有贡献的边都会满足(pre_i<lle ile r),这个可以建出主席树后二维数点实现

    #include<bits/stdc++.h>
    #define LL long long
    #define uLL unsigned long long
    #define db double
    
    using namespace std;
    const int N=2e5+10,inf=1<<30;
    int rd()
    {
    	int x=0,w=1;char ch=0;
    	while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    	return x*w;
    }
    int n,m,q,op,ans,e[N<<1][2];
    int fa[N<<1],ch[N<<1][2],id[N<<1];
    bool tg[N<<1];
    bool nrt(int x){return ch[fa[x]][0]==x||ch[fa[x]][1]==x;}
    void psup(int x){id[x]=min(x<=n?inf:x,min(id[ch[x][0]],id[ch[x][1]]));}
    void rev(int x){if(x) tg[x]^=1,swap(ch[x][0],ch[x][1]);}
    void psdn(int x){if(tg[x]) rev(ch[x][0]),rev(ch[x][1]),tg[x]=0;}
    void ppush(int x)
    {
    	if(nrt(x)) ppush(fa[x]);
    	psdn(x);
    }
    void rot(int x)
    {
    	int y=fa[x],z=fa[y],ty=ch[y][1]==x,w=ch[x][!ty];
    	if(nrt(y)) ch[z][ch[z][1]==y]=x;
    	ch[x][!ty]=y,ch[y][ty]=w;
    	if(w) fa[w]=y;
    	fa[y]=x,fa[x]=z;
    	psup(y);
    }
    void spl(int x)
    {
    	ppush(x);
    	while(nrt(x))
    	{
    		int y=fa[x],z=fa[y];
    		if(nrt(y)) ((ch[y][1]==x)^(ch[z][1]==y))?rot(x):rot(y);
    		rot(x);
    	}
    	psup(x);
    }
    void acs(int x)
    {
    	for(int y=0;x;y=x,x=fa[x])
    		spl(x),ch[x][1]=y,psup(x);
    }
    void mkrt(int x){acs(x),spl(x),rev(x);}
    void split(int x,int y){mkrt(x),acs(y),spl(y);}
    int fdrt(int x)
    {
    	acs(x),spl(x);
    	psdn(x);
    	while(ch[x][0]) x=ch[x][0],psdn(x);
    	return x;
    }
    void link(int i)
    {
    	int x=e[i][0],y=e[i][1];
    	mkrt(x),mkrt(y);
    	fa[x]=fa[y]=i;
    }
    void cut(int i)
    {
    	int x=e[i][0],y=e[i][1];
    	split(x,y);
    	spl(i);
    	ch[i][0]=ch[i][1]=fa[x]=fa[y]=0;
    }
    vector<int> pt[N];
    vector<int>::iterator it;
    int s[N*30],sn[N*30][2],rt[N],tt;
    void inst(int o1,int o2,int x)
    {
    	s[o1]=s[o2]+1;
    	int l=1,r=m;
    	while(l<r)
    	{
    		int mid=(l+r)>>1;
    		if(x<=mid)
    		{
    			sn[o1][0]=++tt,sn[o1][1]=sn[o2][1];
    			o1=sn[o1][0],o2=sn[o2][0];
    			r=mid;
    		}
    		else
    		{
    			sn[o1][0]=sn[o2][0],sn[o1][1]=++tt;
    			o1=sn[o1][1],o2=sn[o2][1];
    			l=mid+1;
    		}
    		s[o1]=s[o2]+1;
    	}
    }
    int quer(int o,int l,int r,int ll,int rr)
    {
    	if(!s[o]||ll>rr) return 0;
    	if(ll<=l&&r<=rr) return s[o];
    	int an=0,mid=(l+r)>>1;
    	if(ll<=mid) an+=quer(sn[o][0],l,mid,ll,rr);
    	if(rr>mid) an+=quer(sn[o][1],mid+1,r,ll,rr);
    	return an;
    }
    
    int main()
    {
    	n=rd(),m=rd(),q=rd(),op=rd();
    	id[0]=inf;
    	for(int i=1;i<=m;++i)
    	{
    		e[i+n][0]=rd(),e[i+n][1]=rd();
    		if(e[i+n][0]==e[i+n][1]) continue;
    		if(fdrt(e[i+n][0])==fdrt(e[i+n][1]))
    		{
    			split(e[i+n][0],e[i+n][1]);
    			int ii=id[e[i+n][1]];
    			pt[ii-n].push_back(i);
    			cut(ii);
    		}
    		else pt[0].push_back(i);
    		link(i+n);
    	}
    	for(int i=1;i<=m;++i)
    	{
    		rt[i]=rt[i-1];
    		for(it=pt[i-1].begin();it!=pt[i-1].end();++it)
    		{
    			int x=*it,las=rt[i];
    			inst(rt[i]=++tt,las,x);
    		}
    	}
    	while(q--)
    	{
    		int l=rd()^(ans*op),r=rd()^(ans*op);
    		ans=n-quer(rt[l],1,m,l,r);
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    linux 系统自签免费ssl证书和nginx配置
    new pdo 连接很慢的原因和解决办法
    Http请求头和响应头(Get和Post)
    亿级Web系统搭建――单机到分布式集群 转载
    php缓存机制
    八大设计模式
    按照子查询结果的顺序进行查询
    Exception in thread "main" java.util.ConcurrentModificationException异常
    理解Maven中的SNAPSHOT版本和正式版本
    IDEA配置GIT
  • 原文地址:https://www.cnblogs.com/smyjr/p/11668046.html
Copyright © 2020-2023  润新知