zoukankan      html  css  js  c++  java
  • LG5227 [AHOI2013]连通图(线段树分治)

    LG5227 [AHOI2013]连通图

    线段树分治板子。这种动态图的问题看都不要看,大概率可以用线段树分治。

    我们有一堆的集合,每次把这个集合的边删掉,问你每个时刻的连通性。

    我们只需要把这个时刻删去的集合里的边删掉,也就是这个区间不用加这条边,按常规把边扔到线段树上,遍历一下,每个点的连通性就出来了。

    拿样例举个例子:

    4 5
    1 2
    2 3
    3 4
    4 1
    2 4
    3
    1 5
    2 2 3
    2 1 2
    
    • 那么 \(1\) 号边在线段树上挂到 \([1,2]\) 区间上。
    • 那么 \(2\) 号边在线段树上挂到 \([1,1]\) 区间上。
    • 那么 \(3\) 号边在线段树上挂到 \([1,1],[3,3]\) 区间上。
    • 那么 \(4\) 号边在线段树上挂到 \([1,3]\) 区间上。
    • 那么 \(5\) 号边在线段树上挂到 \([2,3]\) 区间上。

    遍历即可。

    //Don't act like a loser.
    //This code is written by huayucaiji
    //You can only use the code for studying or finding mistakes
    //Or,you'll be punished by Sakyamuni!!!
    #include<bits/stdc++.h>
    #define int long long
    #define pr pair<int,int>
    using namespace std;
    
    int read() {
    	char ch=getchar();
    	int f=1,x=0;
    	while(ch<'0'||ch>'9') {
    		if(ch=='-')
    			f=-1;
    		ch=getchar();
    	}
    	while(ch>='0'&&ch<='9') {
    		x=x*10+ch-'0';
    		ch=getchar();
    	}
    	return f*x;
    }
    
    const int MAXN=4e5+10,MAXQ=2e5+10;
    
    int n,m,q,cnt,num;
    stack<pr > stk;
    int size[MAXN],father[MAXN],a[MAXN],ans[MAXQ];
    vector<int > edge[MAXQ<<2];
    pr e[MAXN];
    
    pr make_edge(int x,int y) {
    	return make_pair(min(x,y),max(x,y));
    }
    int find(int x) {
    	if(x!=father[x]) {
    		return find(father[x]);
    	}
    	return x;
    }
    void merge(pr s) {
    	int x=find(s.first);
    	int y=find(s.second);
    	if(x==y) {
    		stk.push(make_pair(-1,-1));
    		return ;
    	}
    	num--;
    	if(size[x]>size[y]) {
    		swap(x,y);
    	}
    	father[x]=y;
    	size[y]+=size[x];
    	stk.push(make_pair(x,y));
    }
    void del() {
    	int x=stk.top().first;
    	int y=stk.top().second;
    	stk.pop();
    	if(x==-1) {
    		return ;
    	}
    	num++;
    	father[x]=x;
    	size[y]-=size[x];
    }
    
    void modify(int l,int r,int p,int x,int y,int s) {
    	if(x>y||r<x||y<l) {
    		return ;
    	}
    	if(x<=l&&r<=y) {
    		edge[p].push_back(s);
    		return ;
    	}
    	
    	int mid=(l+r)>>1;
    	modify(l,mid,p<<1,x,y,s);
    	modify(mid+1,r,p<<1|1,x,y,s);
    }
    
    void query(int l,int r,int p) {
    	int sz=edge[p].size();
    	for(int i=0;i<sz;i++) {
    		merge(e[edge[p][i]]);
    	}
    	if(l==r) {
    		if(num==1) {
    			ans[l]=1;
    		}
    		else {
    			ans[l]=0;
    		}
    	}
    	else {
    		int mid=(l+r)>>1;
    		query(l,mid,p<<1);
    		query(mid+1,r,p<<1|1);
    	} 
    	while(sz--) {
    		del();
    	}
    }
    
    signed main() {
    	cin>>n>>m;
    	num=n;
    	for(int i=1;i<=n;i++) {
    		father[i]=i;
    		size[i]=i;
    	} 
    	for(int i=1;i<=m;i++) {
    		e[i]=make_edge(read(),read());
    		a[i]=1;
    	}
    	cin>>q;
    	
    	for(int i=1;i<=q;i++) {
    		int k=read();
    		while(k--) {
    			int c=read();
    			modify(1,q,1,a[c],i-1,c);
    			a[c]=i+1;
    		}
    	}
    	for(int i=1;i<=m;i++) {
    		modify(1,q,1,a[i],q,i);
    	}
    	
    	query(1,q,1);
    	for(int i=1;i<=q;i++) {
    		if(ans[i]) {
    			printf("Connected\n");
    		} 
    		else {
    			printf("Disconnected\n");
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    关于MIME类型问题,浏览器请求到的资源是乱码
    关于vue切换用户,路由表不更新问题
    Flutter环境安装,ios真机调试
    vue使用trackingjs
    js的中文英文排序
    google无法播放mp4 chrome无法播放h264
    写在Blog前
    NOI2010Day1
    菜鸡KLC的中考游记
    ABC161 题解
  • 原文地址:https://www.cnblogs.com/huayucaiji/p/LG5227.html
Copyright © 2011-2022 走看看