• AcWing 239 奇偶游戏 (带权并查集 / 扩展域并查集)


    题目链接:https://www.acwing.com/problem/content/description/241/

    并查集的一个重要功能就是动态维护具有传递性的关系,
    比如:相等,奇偶性等等

    如果传递关系只有一种,比如相等,那就使用普通的并查集来维护即可

    如果传递关系不只有一种,比如本题的奇偶性:

    1. 如果 (x_1)(x_2) 奇偶性相同, (x_2)(x_3) 奇偶性相同,则 (x_1)(x_3) 奇偶性相同(与相等关系一样)
    2. 如果 (x_1)(x_2) 奇偶性相同, (x_2)(x_3) 奇偶性不同,则 (x_1)(x_3) 奇偶性不同
    3. 如果 (x_1)(x_2) 奇偶性不同, (x_2)(x_3) 奇偶性不同,则 (x_1)(x_3) 奇偶性相同

    这时候需要使用边带权的并查集:
    (d[x]) 表示 (x) 与集合的根的奇偶性关系,(0) 相同,(1) 不同
    (find) 的时候更新 (d) 即可,合并时也要更新一下

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    #include<stack>
    #include<queue>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 30010; 
    
    int n, m;
    
    struct Q{
    	int l, r, ans;
    }query[maxn];
    
    char s[10];
    
    int a[maxn], cnt = 0;
    
    int fa[maxn], d[maxn]; // 0 same  1 different
    
    int find(int x){
    	if(fa[x] == x) return x;
    	int root = find(fa[x]); 
    	d[x] ^= d[fa[x]];
    	return fa[x] = root;
    }
    
    ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }
    
    int main(){
    	scanf("%d%d", &n, &m);
    	for(int i = 1; i <= m; ++i){
    		scanf("%d%d%s", &query[i].l, &query[i].r, s);
    		if(s[0] == 'o') query[i].ans = 1; else query[i].ans = 0;
    		a[++cnt] = query[i].r, a[++cnt] = query[i].l - 1;
    	}
    	
    	sort(a + 1, a + 1 + cnt);
    	
    	n = unique(a + 1, a + 1 + cnt) - a - 1; 
    	
    	for(int i = 1; i <= n ; ++i) fa[i] = i;
    	
    	for(int i = 1; i <= m; ++i){
    		int x = lower_bound(a + 1, a + 1 + n, query[i].l - 1) - a;
    		int y = lower_bound(a + 1, a + 1 + n, query[i].r) - a; 		
    
    		int p = find(x), q = find(y); 
    		if(p == q) {
    			if((d[x] ^ d[y]) != query[i].ans){
    				printf("%d
    ",i - 1); return 0;
    			}
    		} else{
    			fa[p] = q;
    			d[p] = d[x] ^ d[y] ^ query[i].ans;
    		}
    	} 
    	printf("%d
    ",m);
    	
    	return 0;
    }
    
  • 相关阅读:
    .NET 二维码生成(ThoughtWorks.QRCode)
    js 异常处理 错误不弹出窗口
    精美的贴子挂件
    .NET 导出到excel
    转:ASP.NET发布WebService操作流程
    Jquery中的CheckBox、RadioButton、DropDownList的取值赋值实现代码
    照片墙
    NET生成缩略图并下载
    QQ分组图案
    .net实现webservice简单实例分享
  • 原文地址:https://www.cnblogs.com/tuchen/p/13956574.html
Copyright © 2020-2023  润新知