AcWing 352. 闇の連鎖

新的思路:
前置题目

时间复杂度

(O(nlogn))

C++ 代码

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<ctime>
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
const int N=2e5+5;
int n,m;
struct Query
{
	int x,y;
	int o;	
	int ans;
	Query(int x,int y,int o) : x(x),y(y),o(o) {}
	Query() {}
}q[4*N];
int cnt=0;
struct Bits
{
	int c[N];
	inline int lowbit(int x) { return x&(-x); }
	inline void update(int x,int y)
	{
		for(;x<=n;x+=lowbit(x)) 
			c[x]+=y;
		return;
	}
	inline int sum(int x)
	{
		int res=0;
		for(;x>=1;x-=lowbit(x)) 
			res+=c[x];
		return res;
	}
}C;
inline bool cmp(const Query &a,const Query &b)
{
	return a.x<b.x;
}
inline bool rule(const Query &a,const Query &b)
{
	return a.o<b.o;
}
//=========================================================
vector<int> v[N];

int dfn[N],dfnu[N],times=0;
void dfs(int x,int fa)
{
	int i,y;
	dfn[x]=++times;
	for(i=0;i<(int)v[x].size();i++) {
		y=v[x][i];
		if(y==fa) continue;
		dfs(y,x);
	}
	dfnu[x]=times;
	return;
}
int a[N],s[N];
vector<int> cc[N];
int ans=0;
int main()
{
	freopen("astronaut.in","r",stdin);
	freopen("astronaut.out","w",stdout);
	int i,j,k;
	int x,y;
	scanf("%d%d",&n,&m);
	for(i=1;i<=n-1;i++) {
		scanf("%d%d",&x,&y);
		v[x].push_back(y);
		v[y].push_back(x);
	}
	dfs(1,0);
	for(i=1;i<=m;i++) {
		scanf("%d%d",&x,&y);
		if(x==y) continue;
//		insert(1,dfn[x],dfn[y],1,n);
		a[dfn[x]]++; a[dfn[y]]++;
		cc[dfn[x]].push_back(dfn[y]);
	}
	for(i=1;i<=n;i++) {
		cnt++; q[cnt]=Query(dfnu[i],dfnu[i],cnt);
		cnt++; q[cnt]=Query(dfn[i]-1,dfn[i]-1,cnt);
		cnt++; q[cnt]=Query(dfnu[i],dfn[i]-1,cnt);
		cnt++; q[cnt]=Query(dfn[i]-1,dfnu[i],cnt);
	}
	sort(q+1,q+cnt+1,cmp);
	for(i=1;i<=cnt;i++) {
		for(j=q[i-1].x+1;j<=q[i].x;j++) {
			for(k=0;k<(int)cc[j].size();k++) 
				C.update(cc[j][k],1);
		}
		q[i].ans=C.sum(q[i].y);
	} 
	sort(q+1,q+cnt+1,rule);
	for(i=1;i<=n;i++) 
		s[i]=s[i-1]+a[i];
	for(x=2;x<=n;x++) {
		int tmp=s[dfnu[x]]-s[dfn[x]-1]-2*(q[4*(x-1)+1].ans+q[4*(x-1)+2].ans
		    -q[4*(x-1)+3].ans-q[4*(x-1)+4].ans);
		if(tmp==0) ans+=m;
		else if(tmp==1) ans++;//,printf("%d %d
",x,y);
	}
//	Dp(1,0);
	cout<<ans;
	return 0;
}
原文地址:https://www.cnblogs.com/cjl-world/p/14054165.html