zoukankan      html  css  js  c++  java
  • 联赛模拟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
    ",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;
    }
    
  • 相关阅读:
    随机森林算法参数调优
    BAYES和朴素BAYES
    阿里云 金融接口 token PHP
    PHP mysql 按时间分组 表格table 跨度 rowspan
    MySql按周,按月,按日分组统计数据
    PHP 获取今日、昨日、本周、上周、本月的等等常用的起始时间戳和结束时间戳的时间处理类
    thinkphp5 tp5 会话控制 session 登录 退出 检查检验登录 判断是否应该跳转到上次url
    微信 模板消息
    php 腾讯 地图 api 计算 坐标 两点 距离 微信 网页 WebService API
    php添加http头禁止浏览器缓存
  • 原文地址:https://www.cnblogs.com/Lour688/p/13910369.html
Copyright © 2011-2022 走看看