并查集对状态的维护

匿名 (未验证) 提交于 2019-12-02 23:34:01
版权声明:本人所有 https://blog.csdn.net/mxYlulu/article/details/89881514

这里的题目一般都是维护状态,每个集合表示的是一种状态(一般为两个)

题目会询问第一次状态冲突的时候[并查集添加状态的时候发现已有状态并且状态不对]

数据结构K题

K题讲述的是:告诉你n个区间的和的奇偶,判断第一个矛盾的地方。

区间和的奇偶可以转换成可以维护的前缀和之差的奇偶,和为奇,前缀和sum[l-1]和sum[r]一定奇偶不同。

前者奇后者偶,或者反过来。这两种状态我们都添加到并查集里去。

那么怎么表示哪个是奇数呢,0~n为奇数,n+1~2*n+1为偶数。类似于罪犯分配问题。后者做过的前提我还没做出来K题,看到题解才恍然大悟,脑子不行就要靠刷题弥补。

 #include<bits/stdc++.h> #define FOR(i,a,b) for(int i=a;i<=b;i++) #define ll long long using namespace std;  const int MAXN = 1000050*2;  int n,m; int f[MAXN];  struct UnionSet {     UnionSet(int n) {         for (int i = 0; i <= 2*n+1; i++) {             f[i] = i;         }     }     UnionSet(){}      void uni(int x, int y) {         f[find(x)] = find(y);     }      bool query(int x, int y) {         return find(x) == find(y);     }      int find(int x) {         return f[x] == x ? x : (f[x] = find(f[x]));     }  } us;  int main(){     cin>>n>>m;     char ch[10];     us=UnionSet(n);     FOR(i,1,m){         int x,y;         scanf("%d%d%s",&x,&y,ch);         x--;         if(ch[0]=='e'){             if(us.query(x,y+n+1)||us.query(x+n+1,y)){                 cout<<i-1<<endl;                 return 0;             }             us.uni(x,y);             us.uni(x+n+1,y+n+1);         }         else{             if(us.query(x,y)||us.query(x+n+1,y+n+1)){                 cout<<i-1<<endl;                 return 0;             }             us.uni(x+n+1,y);             us.uni(x,y+n+1);         }     }     cout<<"ORZQHQH"<<endl; } 

罪犯分配问题

文章来源: https://blog.csdn.net/mxYlulu/article/details/89881514
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!