联赛模拟27_地理课

转化一下题意,m条边只有一段时间出现在图中。

可以线段树分治+并查集维护,并查集要按秩合并因为要支持撤销

Code
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iostream>
#include <unordered_map>
#define rint register int
#define L (rt*2)
#define R (rt*2+1)
using namespace std;

const int maxn=1e5+5;
const int M=1e9+7;
struct Node{
	int x;
	int fa_x,siz_x,rk_x;
}a[maxn*2];
int n,m,tot;
int op[maxn],x[maxn],y[maxn],del_time[maxn];
int ny[maxn],fa[maxn],siz[maxn],rk[maxn];
unordered_map < long long,int > app;
vector < pair<int,int> > vec[maxn*4];

char buf[1<<20],*p1,*p2;
#define gc() (p1==p2?(p2=buf+fread(p1=buf,1,1<<20,stdin),p1==p2?EOF:*p1++):*p1++)
#define read() ({\
	rint x=0;register bool f=0;register char ch=gc();\
	while(ch<'0'||ch>'9') f|=ch=='-',ch=gc();\
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch&15),ch=gc();\
	f?-x:x;\
})

void pre(){
	for(int i=1;i<=n;++i) fa[i]=i,siz[i]=1;
	ny[1]=1;
	for(int i=2;i<=n;++i) ny[i]=1ll*(M-M/i)*ny[M%i]%M;
}

void modify(int rt,int l,int r,int ql,int qr,int x,int y){
	if(ql<=l&&r<=qr) return vec[rt].push_back(make_pair(x,y)),void();
	int mid=(l+r)/2;
	if(ql<=mid) modify(rt*2,l,mid,ql,qr,x,y);
	if(qr> mid) modify(rt*2+1,mid+1,r,ql,qr,x,y);
}

int find(rint x){
	while(fa[x]!=x) x=fa[x];
	return x;
}

void merge(rint x,rint y){
	a[++tot]=(Node){x,fa[x],siz[x],rk[x]};
	a[++tot]=(Node){y,fa[y],siz[y],rk[y]};
	if(rk[x]==rk[y]) rk[y]++;
	if(rk[x]>rk[y]) swap(x,y);
	fa[x]=y,siz[y]+=siz[x];
}

void solve(int rt,int l,int r,int ans){
	rint tmp=tot;
	for(rint i=0;i<(int)vec[rt].size();++i){
		const rint xx=find(vec[rt][i].first),yy=find(vec[rt][i].second);
		if(xx==yy) continue;
		ans=1ll*ans*ny[siz[xx]]%M*ny[siz[yy]]%M*(siz[xx]+siz[yy])%M;
		merge(xx,yy);
	}
	if(l==r) printf("%d\n",ans);
	else{
		rint mid=(l+r)/2;
		solve(rt*2,l,mid,ans),solve(rt*2+1,mid+1,r,ans);
	}
	while(tot>tmp){
		const rint xx=a[tot].x;
		const rint ff=a[tot].fa_x;
		const rint ss=a[tot].siz_x;
		const rint rr=a[tot].rk_x;
		fa[xx]=ff,siz[xx]=ss,rk[xx]=rr;
		--tot;
	}
}

int main(){
	freopen("geography.in","r",stdin);
	freopen("geography.out","w",stdout);
	n=read(),m=read();
	pre();
	for(rint i=1;i<=m;++i){
		op[i]=read(),x[i]=read(),y[i]=read();
		if(x[i]>y[i]) swap(x[i],y[i]);
		const long long hh=1ll*x[i]*n+y[i];
		if(op[i]==1){
			app[hh]=i;
			del_time[i]=m;
			continue;
		}
		else del_time[app[hh]]=i-1;
	}
	for(rint i=1;i<=m;++i) if(del_time[i]) modify(1,1,m,i,del_time[i],x[i],y[i]);
	solve(1,1,m,1);
	return 0;
}
posted @ 2020-11-01 17:34  liuzhaoxu  阅读(83)  评论(0编辑  收藏  举报