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;
    }
    
  • 相关阅读:
    强化学习的基本迭代方法
    基于文本描述的事务聚类
    学习强化学习之前需要掌握的3种技能
    其它 华硕 ASAU S4100U 系统安装 win10安装 重装系统 Invalid Partition Table 解决
    数据分析 一些基本的知识
    Python 取样式的内容 合并多个文件的样式 自定义样式
    电商 Python 生成补单公司需要的评论格式3
    SpringBlade 本地图片上传 生成缩略图
    SQL Server 字符串截取
    SpringBlade 本地图片上传
  • 原文地址:https://www.cnblogs.com/LSlzf/p/12196272.html
Copyright © 2011-2022 走看看