zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    [转]拓扑排序
    [转]C++ string学习
    二叉树的前序遍历
    My Solution to Lowest Common Ancestor of a Binary Tree Part I(TopDown Approach)
    求二叉树节点总数
    二叉树的中序遍历
    轻松搞定面试中的二叉树题目
    VS2005 CrystalReport开发Web应用
    ASP.NET 2.0移动开发入门之使用模拟器
    [原创]Ajax UpLoadFile 多个大文件上传控件,已更新。
  • 原文地址:https://www.cnblogs.com/thunder-110/p/10445184.html
Copyright © 2011-2022 走看看