Parity game(带权并查集+离散化)

题目链接  //kuangbin

题意:

  现在你和你的朋友正在玩一种游戏。 你的朋友写下一串0和1的序列,然后你选择其中一串子序列(如[3,5])并且问他这个序列是包含奇数个1还是偶数个1(和是奇数还是偶数)。 你可以问你的朋友任意个问题,而你的朋友会回答你的问题。 你的任务是猜出整个朋友的序列。但是,你发现你的朋友告诉你的信息可能有误,所以你想写一个程序来指出他的错误。这个程序应该接受一系列你的问题和答案。程序的目标是找到第一个错误的答案。

思路:

  由之前做树状数组的题目经验得到,左区间可以-1,使得连贯起来。

  因为1e9很大数组开不下,所以离散化(这一步要在左区间-1的步骤之后)。

  带权。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include <cctype>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<cmath>
 7 #include<string>
 8 #include<cmath>
 9 #include<set>
10 #include<vector>
11 #include<stack>
12 #include<queue>
13 #include<map>
14 using namespace std;
15 #define ll long long
16 #define mem(a,x) memset(a,x,sizeof(a))
17 #define se second
18 #define fi first
19 const ll mod=998244353;
20 const int INF= 0x3f3f3f3f;
21 const int N=2e5+5;
22 
23 int n,m;
24 int f[N];
25 int book[N];
26 int sum[N];
27 vector<int>v;
28 
29 struct node
30 {
31     int f,s;
32 }a[N];
33 string str;
34 
35 int getf(int x)
36 {
37     if(x!=f[x])
38     {
39         int t=f[x];
40         f[x]=getf(f[x]);
41         sum[x]+=sum[t]; // 其实sum[x]^=sum[t]也行,更快,110ms
42     }
43     return f[x];
44 }
45 int main()
46 {
47     cin>>n>>m;
48     int ans=0;
49     for(int i=0;i<=N;i++) f[i]=i;
50 
51     for(int i=1;i<=m;i++)
52     {
53         scanf("%d%d",&a[i].f,&a[i].s);
54         if(a[i].f>a[i].s) swap(a[i].f,a[i].s);
55         a[i].f--;
56         v.push_back(a[i].f);
57         v.push_back(a[i].s);
58 
59         cin>>str;
60         if(str[0]=='o') book[i]=1;
61         else book[i]=0;
62     }
63     sort(v.begin(),v.end());
64     v.erase(unique(v.begin(),v.end()) , v.end());
65 
66     for(int i=1;i<=m;i++)
67     {
68         a[i].f= lower_bound(v.begin(),v.end(),a[i].f)-v.begin()+1;
69         a[i].s= lower_bound(v.begin(),v.end(),a[i].s)-v.begin()+1;
70         int f1=getf(a[i].f);
71         int f2=getf(a[i].s);
72         if(f1!=f2)
73         {
74             f[f1]=f2;
75             sum[f1]=sum[a[i].s]+book[i]-sum[a[i].f]; //sum[f1]=sum[a[i].s]^book[i]^sum[a[i].f]
76             ans++;
77         }
78         else
79         {
80             if( abs(sum[a[i].f]-sum[a[i].s]) %2 != book[i] )  break; //一定要abs。
81             else ans++;
82         }
83     }
84     cout<<ans<<endl;
85 
86 }
原文地址:https://www.cnblogs.com/thunder-110/p/10445184.html