zoukankan      html  css  js  c++  java
  • [CF901C] Bipartite Segments

    题目大意

    给你一个有(n)个点的无向图,没有偶环。我们把节点标记为(1..n)

    你需要回答(q)个询问,每一个询问由一个区间[L,R](1<=L<=R<=n)组成,你需要计算出有多少个点对[x,y](L<=x<=y<=R),满足由[x,y]之间的所有点组成的子图是一个二分图。

    输入数据第一行两个整数 (n,m (1le nle 3 imes 10^5,1le mle 3 imes10^5))代表点数和边数 接下来的(m)行,每行两个整数,表示一条无向边,保证无自环,保证无重边

    一个整数 (q(1le qle3 imes 10^5)),表示询问个数

    接下来q行,每行一个询问[L,R]

    对于每个询问,输出一个整数,表示满足条件的点对[x,y]的个数

    解析

    首先想到的一定是”没有偶环“这一特殊的性质。仔细思考一下,没有偶环,也就等价于没有环套环的情况,因为如果有两个环套在一起,如果两个简单环都是奇环,那么一定会产生一个偶环(具体证明可以自行解决)。那么,原图就是一个仙人掌,并且所有环都是奇环。

    接下来考虑询问。二分图的条件是没有奇环,那么满足要求的区间就不能包括任何一个环。因此,首先用Tarjan求边双连通分量,把所有环找出来,记第(i)个环中最小的点为(L[i]),最大的点为(R[i]),那么对于一个区间([1,L[i]])中的点,以它为左端点的区间一定不能覆盖(R[i])及其以后的点。所以,我们可对每个点(i)求出它最远能够覆盖到的点(nxt[i])(线段树区间修改最小值),对于一个询问区间([l,r]),二分找到满足(nxt[i]<=r)的最右边的点,该点左边的用(nxt)统计答案((sum nxt[i]-i)),右边的所有子区间都满足条件,相加即为询问的答案。

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define int long long
    #define N 300002
    using namespace std;
    const int S=600001;
    const int inf=1<<30;
    struct SegmentTree{
    	int dat,add;
    }t[N*4];
    int head[N],ver[N*2],nxt[N*2],l;
    int n,m,q,i,tim,dfn[N],low[N],top,s[N],cnt,scc[N],L[N],R[N],a[N],sum[N];
    bool cut[N*2];
    int read()
    {
    	char c=getchar();
    	int w=0;
    	while(c<'0'||c>'9') c=getchar();
    	while(c<='9'&&c>='0'){
    		w=w*10+c-'0';
    		c=getchar();
    	}
    	return w;
    }
    void insert(int x,int y)
    {
    	ver[l]=y;
    	nxt[l]=head[x];
    	head[x]=l;
    	l++;
    }
    void Tarjan(int x,int pre)
    {
    	dfn[x]=low[x]=++tim;
    	for(int i=head[x];i!=-1;i=nxt[i]){
    		int y=ver[i];
    		if(!dfn[y]){
    			Tarjan(y,i);
    			low[x]=min(low[x],low[y]);
    			if(low[y]>dfn[x]) cut[i]=cut[i^1]=1;
    		}
    		else if(i!=(pre^1)) low[x]=min(low[x],dfn[y]);
    	}
    }
    void dfs(int x)
    {
    	scc[x]=cnt;
    	L[cnt]=min(L[cnt],x);
    	R[cnt]=max(R[cnt],x);
    	for(int i=head[x];i!=-1;i=nxt[i]){
    		if(cut[i]) continue;
    		int y=ver[i];
    		if(!scc[y]) dfs(y);
    	}
    }
    void update(int p)
    {
    	t[p].dat=min(t[p*2].dat,t[p*2+1].dat);
    }
    void spread(int p)
    {
    	if(t[p].add!=inf){
    		t[p*2].add=min(t[p*2].add,t[p].add);
    		t[p*2+1].add=min(t[p*2+1].add,t[p].add);
    		t[p*2].dat=min(t[p*2].dat,t[p].add);
    		t[p*2+1].dat=min(t[p*2+1].dat,t[p].add);
    		t[p].add=inf;
    	}
    }
    void build(int p,int l,int r)
    {
    	t[p].add=t[p].dat=inf;
    	if(l==r) return;
    	int mid=(l+r)/2;
    	build(p*2,l,mid);
    	build(p*2+1,mid+1,r);
    }
    void change(int p,int l,int r,int ql,int qr,int x)
    {
    	if(ql<=l&&r<=qr){
    		t[p].dat=min(t[p].dat,x);
    		t[p].add=min(t[p].add,x);
    		return;
    	}
    	int mid=(l+r)/2;
    	spread(p);
    	if(ql<=mid) change(p*2,l,mid,ql,qr,x);
    	if(qr>mid) change(p*2+1,mid+1,r,ql,qr,x);
    	update(p);
    }
    int ask(int p,int l,int r,int x)
    {
    	if(l==r) return t[p].dat;
    	int mid=(l+r)/2;
    	spread(p);
    	if(x<=mid) return ask(p*2,l,mid,x);
    	return ask(p*2+1,mid+1,r,x);
    }
    signed main()
    {
    	memset(head,-1,sizeof(head));
    	memset(L,0x3f,sizeof(L));
    	n=read();m=read();
    	for(i=1;i<=m;i++){
    		int u=read(),v=read();
    		insert(u,v);
    		insert(v,u);
    	}
    	for(i=1;i<=n;i++){
    		if(!dfn[i]) Tarjan(i,S);
    	}
    	for(i=1;i<=n;i++){
    		if(!scc[i]) cnt++,dfs(i);
    	}
    	build(1,1,n);
    	for(i=1;i<=cnt;i++){
    		if(R[i]!=L[i]) change(1,1,n,1,L[i],R[i]);
    	}
    	for(i=1;i<=n;i++){
    		a[i]=ask(1,1,n,i);
    		sum[i]=sum[i-1]+a[i]-i;
    	}
    	q=read();
    	for(i=1;i<=q;i++){
    		int x=read(),y=read();
    		int p=upper_bound(a+x,a+y+1,y)-a-1;
    		int num1=sum[p]-sum[x-1],num2=y-p;
    		printf("%lld
    ",num1+num2*(num2+1)/2);
    	}
    	return 0;
    }
    
  • 相关阅读:
    【SCOI 2011】 糖果
    【POJ 3159】 Candies
    【POJ 1716】 Integer Intervals
    【POJ 2983】 Is the information reliable?
    【POJ 1364】 King
    【POJ 1201】 Intervals
    【POJ 1804】 Brainman
    6月10日省中提高组题解
    【POJ 3352】 Road Construction
    【POJ 1144】 Network
  • 原文地址:https://www.cnblogs.com/LSlzf/p/12196272.html
Copyright © 2011-2022 走看看