zoukankan      html  css  js  c++  java
  • CF576E Painting Edges [线段树分治,可撤销并查集]

    板子题.jpg
    不同颜色互不影响,所以判断每种颜色有没有奇环就可以了,顺便判一下联不联通.jpg

    #include <bits/stdc++.h>
    #define rep(i , x , y) for(register int i = (x) , _## i = (y + 1) ; i < _## i ; i ++)
    #define Rep(i , x , y) for(register int i = (x) , _## i = (y - 1) ; i > _## i ; i --)
    using namespace std ;
    //#define int long long
    using ll = long long ;
    using pii = pair < int , int > ;
    const static int _ = 1 << 20 ;
    char fin[_] , * p1 = fin , * p2 = fin ;
    inline char gc() {
    	return (p1 == p2) && (p2 = (p1 = fin) + fread(fin , 1 , _ , stdin) , p1 == p2) ? EOF : * p1 ++ ;
    }
    inline int read() {
    	bool sign = 1 ;
    	char c = 0 ;
    	while(c < 48) ((c = gc()) == 45) && (sign = 0) ;
    	int x = (c & 15) ;
    	while((c = gc()) > 47) x = (x << 1) + (x << 3) + (c & 15) ;
    	return sign ? x : -x ;
    }
    template < class T > void print(T x , char c = '
    ') {
    	(x == 0) && (putchar(48)) , (x < 0) && (putchar(45) , x = -x) ;
    	static char _st[100] ;
    	int _stp = 0 ;
    	while(x) _st[++ _stp] = x % 10 ^ 48 , x /= 10 ;
    	while(_stp) putchar(_st[_stp --]) ;
    	putchar(c) ;
    }
    template < class T > void cmax(T & x , T y) {
    	(x < y) && (x = y) ;
    }
    template < class T > void cmin(T & x , T y) {
    	(x > y) && (x = y) ;
    }
    
    int N , M , K , Q ;
    const int SZ = 5e5 + 10 ;
    int id[SZ] , las[SZ] , L[SZ] , R[SZ] ;
    int pre[SZ] , col[SZ] ;
    struct Node {
    	int u , v , col ;
    	bool s ;
    } edge[SZ << 1] ;
    struct Union {
    	int fa[SZ] , f[SZ] , d[SZ] ;
    	int find(int x) {
    		return x == fa[x] ? x : find(fa[x]) ;
    	}
    	int dis(int x) {
    		int y = 0 ;
    		while(x ^ fa[x]) {
    			y ^= f[x] ;
    			x = fa[x] ;
    		}
    		return y ;
    	}
    	void cancel(Node a) {
    		f[fa[a.u] = a.u] = 0 ;
    		d[a.v] -= a.s ;
    	}
    	bool connected(int x , int y) {
    		return find(x) == find(y) ;
    	}
    	Node Merge(int x , int y , int col) {
    		int fx = find(x) , fy = find(y) ;
    		if(d[fx] > d[fy]) swap(fx , fy) , swap(x , y) ;
    		int w = dis(x) ^ dis(y) ^ 1 ;
    		Node res = { fx , fy , col , 0 } ;
    		f[fx] = w ; fa[fx] = fy ;
    		if(d[fx] == d[fy]) {
    			++ d[fy] ;
    			res.s |= 1 ;
    		}
    		return res ;
    	}
    } G[55] ;
    void cancel(stack < Node > s) {
    	while(s.size()) {
    		G[s.top().col].cancel(s.top()) ;
    		s.pop() ;
    	}
    }
    vector < int > vec[SZ << 2] ;
    void upd(int a , int b , int l , int r , int rt , int id) {
    //	print(l , ' ') ; print(r , '
    ') ;
    	if(a <= l && r <= b) {
    		vec[rt].push_back(id) ;
    		return ;
    	}
    	int mid = l + r >> 1 ;
    	if(a <= mid) upd(a , b , l , mid , rt << 1 , id) ;
    	if(b > mid) upd(a , b , mid + 1 , r , rt << 1 | 1 , id) ;
    }
    void solve(int l , int r , int k) {
    	stack < Node > s ;
    	for(auto Id : vec[k]) {
    		Node e = edge[Id] ;
    		if(! e.col) continue ;
    		int u = e.u , v = e.v , col = e.col ;
    		if(G[col].connected(u , v)) continue ;
    		s.push(G[col].Merge(u , v , col)) ;
    	}
    	if(l == r) {
    		Node e = edge[id[l]] ;
    		int w = G[col[l]].dis(e.u) ^ G[col[l]].dis(e.v) ^ 1 ;
    		bool t = G[col[l]].connected(e.u , e.v) ;
    		cancel(s) ;
    		if(! t || ! w) {
    			puts("YES") ;
    			edge[id[l]].col = col[l] ;
    			return ;
    		}
    		else {
    			puts("NO") ;
    			return ;
    		}
    	}
    	int mid = l + r >> 1 ;
    	solve(l , mid , k << 1) ;
    	solve(mid + 1 , r , k << 1 | 1) ;
    	cancel(s) ;
    }
    
    signed main() {
    #ifdef _WIN64
    	freopen("testdata.in" , "r" , stdin) ;
    #endif
    	N = read() ; M = read() ; K = read() ; Q = read() ;
    	rep(i , 1 , K) 
    		rep(j , 1 , N) G[i].fa[j] = j ;
    	rep(i , 1 , M) {
    		int x = read() , y = read() ;
    		edge[i] = { x , y , 0 } ;
    	}
    	rep(i , 1 , Q) {
    		int x = read() , y = read() ;
    		id[i] = x ; col[i] = y ;
    		if(las[x]) R[las[x]] = i - 1 ;
    		pre[i] = las[x] ;
    		las[x] = i ;
    		L[i] = i + 1 ;
    		R[i] = Q ;
    	}
    	rep(i , 1 , Q)
    		if(L[i] <= R[i]) upd(L[i] , R[i] , 1 , Q , 1 , id[i]) ;
    	solve(1 , Q , 1) ;
    //	puts("OK") ;
    	return 0 ;
    }
    
  • 相关阅读:
    如何用Tensorflow训练模型成pb文件和和如何加载已经训练好的模型文件
    hbase rowkey 设计
    hbase集群region数量和大小的影响
    为什么不建议在hbase中使用过多的列簇
    hive explode 行拆列
    通过livy向CDH集群的spark提交任务
    case when多条件
    spark sql/hive小文件问题
    SQL join
    spark任务调度模式,动态资源分配
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/12838907.html
Copyright © 2011-2022 走看看