poj1733

题目连接:POJ - 1733

离散化+带权并查集

关于离散化:

比如本题,如果左端点不减1,那么如何表示某个点是不是一呢

比如这组输入5 5 0,表示5这个位置是一

但是你一开始初始化的时候rk[5]=0已经认为5这个位置是0了

所以我们用(l-1,r) 来表示对应的区间

如此一来初始化的零就不代表实际意义了

 1 #include<algorithm>
 2 #include<cstdio>
 3 #include<cstring>
 4
 5 using namespace  std;
 6 const int maxn=200010;
 7 int f[maxn],rk[maxn];
 8 int X[maxn];
 9 int l[maxn],r[maxn],d[maxn];
10 char s[6];
11 int n,m;
12 void init()
13 {
14     for(int i=0;i<maxn;i++)
15     {
16         f[i]=i;
17         rk[i]=0;
18     }
19 }
20
21 int gf(int x)
22 {
23     if(x!=f[x])
24     {
25         int t=f[x];
26         f[x]=gf(t);
27         rk[x]=(rk[x]+rk[t])%2;
28     }
29     return f[x];
30 }
31 int BIN(int *a,int n,int x)
32 {
33     int l=0,r=n-1;
34     while(l<=r)
35     {
36         int m=(l+r)>>1;
37         if(a[m]==x) return m;
38         if(a[m]>x) r=m-1;
39         else l=m+1;
40     }
41     return -1;
42 }
43 int main()
44 {
45     while(scanf("%d%d",&n,&m)!=EOF)
46     {
47         init();
48         int cnt=0;
49         int a,b;
50         for(int i=0;i<m;i++)
51         {
52             scanf("%d%d%s",&a,&b,s);
53             if(b<a) swap(a,b);
54             l[i]=a;
55             r[i]=b;
56             X[cnt++]=l[i]-1;
57             X[cnt++]=r[i];
58             if(s[0]==‘e‘) d[i]=0;
59             else d[i]=1;
60         }
61         sort(X,X+cnt);
62         int ct=1;
63         for(int i=1;i<cnt;i++) if(X[i]!=X[i-1]) X[ct++]=X[i];  //去重
64         int ok=1,ans=m;
65         for(int i=0;i<m&&ok;i++)
66         {
67             int a=BIN(X,ct,l[i]-1);
68             int b=BIN(X,ct,r[i]);
69             int pa=gf(a);
70             int pb=gf(b);
71             if(pa!=pb)
72             {
73                 f[pb]=pa;
74                 rk[pb]=(rk[a]+d[i]-rk[b]+2)%2;
75             }
76             if(pa==pb&&(rk[a]+d[i])%2!=rk[b])  //此行忘记取模WA好久好久没发现错误。。。。
77             {
78                 ok=0;
79                 ans=i;
80             }
81
82         }
83         printf("%d\n",ans);
84     }
85 }
时间: 2025-01-01 08:22:10

poj1733的相关文章

【poj1733】 Parity game

http://poj.org/problem?id=1733 (题目链接) 题意 一个由0,1组成的序列,每次给出一段区间的奇偶,问哪一条信息不合法. Solution 并查集. 题目中序列的长度有很大,单纯搜索一定会TLE. 我们用s[i]表示前i个数的前缀和,那么a b even意味着s[b]和s[a-1]的奇偶性相同.a b odd意味着s[b]与s[a-1]的奇偶性不同.于是我们根据奇偶性的不同,用并查集依次处理他们之间的关系.当某条信息出现与并查集中记录的信息不符合时,则此信息不合法.

POJ1733 - Parity game - 并查集

这道题是带权并查集,只需要把权设成0或1就行,分别表示与根节点的关系.因为10亿个点,所以要用到离散化 #include<iostream> #include<stdio.h> #include<algorithm> using namespace std; int p[10005]; int dis[10005]; int ran[10005]; int tot; struct num { char oe[10]; int st,ed; int id; }po[500

【POJ1733】Parity game

[POJ1733]Parity game 题面 vjudge 题解 比较简单的分类并查集 将一个查询操作看作前缀和\(s_r-s_{l-1}\)的奇偶性 将每个点拆成一奇一偶然后分别连边即可 如果一个点的奇点和偶点被连在一起了就判无解即可 代码 #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include

poj1733(种类并查集+离散化)

题目链接: http://poj.org/problem?id=1733 题意: 输入n表示有一个长度为n的0,1字符串, m表示接下来有m行输入, 接下来的m行输入中x, y, even表示第x到第y个字符中间1的个数为偶数个, x, y, odd表示第x到第y个字符中间1的个数为奇数个, 若m句话中第k+1是第一次与前面的话矛盾, 输出k; 思路: 若x, y之间1的个数为偶数个, 那么1~x 与1~y中1的个数同奇偶性, 反之则异奇偶性, 我们可以将其理解为若输入x, y, even, 即

【POJ1733】【带标记并查集】Parity game

Description Now and then you play the following game with your friend. Your friend writes down a sequence consisting of zeroes and ones. You choose a continuous subsequence (for example the subsequence from the third to the fifth digit inclusively) a

POJ1733 Parity game (美丽的jo)

Description Now and then you play the following game with your friend. Your friend writes down a sequence consisting of zeroes and ones. You choose a continuous subsequence (for example the subsequence from the third to the fifth digit inclusively) a

poj1733 Parity Game(扩展域并查集)

描述 Now and then you play the following game with your friend. Your friend writes down a sequence consisting of zeroes and ones. You choose a continuous subsequence (for example the subsequence from the third to the fifth digit inclusively) and ask hi

并查集练习2(带权并查集)

明天旅游去爬山逛庙玩,今天练一天然后早早睡觉啦~ poj1703 Find them, Catch them (带权并查集) 1 #include<cstdio> 2 const int N=1e5+1; 3 int f[N]; 4 int r[N];//表示与父节点的关系,0同类,1不同类 5 int n; 6 void init(){ 7 for(int i=1;i<=n;++i){ 8 f[i]=i; r[i]=0; 9 } 10 } 11 int fin(int x){ 12 i

题单二:图论500

http://wenku.baidu.com/link?url=gETLFsWcgddEDRZ334EJOS7qCTab94qw5cor8Es0LINVaGMSgc9nIV-utRIDh--2UwRLvsvJ5tXFjbdpzbjygEdpGehim1i5BfzYgYWxJmu ==========  以下是最小生成树+并查集=========================[HDU]1213         How Many Tables        基础并查集★1272         小