POJ1733-离散化+带权并查集

Parity game
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 8342   Accepted: 3248

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) and ask him, whether this subsequence contains even or odd number of ones. Your friend answers your question and you can ask him about another subsequence and so on. Your task is to guess the entire sequence of numbers. 

You suspect some of your friend's answers may not be correct and you want to convict him of falsehood. Thus you have decided to write a program to help you in this matter. The program will receive a series of your questions together with the answers you have received from your friend. The aim of this program is to find the first answer which is provably wrong, i.e. that there exists a sequence satisfying answers to all the previous questions, but no such sequence satisfies this answer.

Input

The first line of input contains one number, which is the length of the sequence of zeroes and ones. This length is less or equal to 1000000000. In the second line, there is one positive integer which is the number of questions asked and answers to them. The number of questions and answers is less or equal to 5000. The remaining lines specify questions and answers. Each line contains one question and the answer to this question: two integers (the position of the first and last digit in the chosen subsequence) and one word which is either `even' or `odd' (the answer, i.e. the parity of the number of ones in the chosen subsequence, where `even' means an even number of ones and `odd' means an odd number).

Output

There is only one line in output containing one integer X. Number X says that there exists a sequence of zeroes and ones satisfying first X parity conditions, but there exists none satisfying X+1 conditions. If there exists a sequence of zeroes and ones satisfying all the given conditions, then number X should be the number of all the questions asked.

Sample Input

10
5
1 2 even
3 4 odd
5 6 even
1 6 even
7 10 odd

Sample Output

3


题目大意: 给你一串长度为n的01串,给你m个操作,每次操作为判断子串[x,y]内1的个数为奇数还是偶数,求x表示前x个操作没有矛                    

                   盾,第x+1个操作与前面的相矛盾(除了全部都没有矛盾)

题目思路:一开始看到这个题没看懂题目意思,还是英语太渣了,后面看了其他大佬们的博客才真正知道题意,然后想了会并没有                     

                    想到用并查集怎么做,然后又去看别人的博客 写到一个模型才恍然大悟,[x,y]区间的1的个数其实可以表示为                    

                    sum(y)-sum(x-1),是不是很像树状数组啊?,其实是并查集,这样就可以联系并查集了,

                   区间x,y 就可以换成 x-1,y 了 ,比如 1 2 e  3 4 o 5 6 e 1 6 e 去过不转换的话 1 6 与 3 4 就没有联系了,转换后的话就是                     

                   0 2 e 2 4 o 4 6 e 0 6 e这样就可以用带权并查集做了,至于数据范围离散化下就ok了

AC代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;

const int maxn = 10050;
int pre[maxn],a[maxn],rk[maxn];
struct st{
    int l,r;
    char q[10];
}s[maxn];
int n,m;

int get(int x){
    if(x!=pre[x]){
        int tmp = pre[x];
        pre[x] = get(pre[x]);
        rk[x]=(rk[x]+rk[tmp])%2;
    }
    return pre[x];
}

int main()
{
       while(~scanf("%d%d",&n,&m)){
          int cnt = 0;
          for(int i=0;i<m;i++){
             scanf("%d%d%s",&s[i].l,&s[i].r,s[i].q);
             s[i].l--;
             a[cnt++]=s[i].l,a[cnt++]=s[i].r;
          }
          // 离散化
          sort(a,a+cnt);
          map<int,int>mp;
          cnt = unique(a,a+cnt)-a;
          for(int i=0;i<cnt;i++){
                pre[i]=i,rk[i]=0;
                mp[a[i]]=i;
          }
          int ans = 0;
          for(int i=0;i<m;i++){
             int x = mp[s[i].l],y = mp[s[i].r];
             int xx = get(x);
             int yy = get(y);
             if(xx!=yy){
                pre[xx]=yy;
                if(s[i].q[0]=='e')          //偶数边的权值为0
                rk[xx]=(rk[x]+rk[y])%2;
                else rk[xx]=(rk[x]+rk[y]+1)%2;    //奇数边的权值为1
                ans++;
             }
             else {
                if(rk[x]==rk[y]&&s[i].q[0]=='o')break;    
                if(rk[x]!=rk[y]&&s[i].q[0]=='e')break;
                ans++;
             }
          }
          printf("%d\n",ans);

       }

    return 0;
}






全部评论

相关推荐

05-21 18:32
已编辑
湖南工学院 Java
这条干货多数是给i人朋友们分享的,知道你们开不了口,可以试试我说的这些方法1.调整心态:接受初期的尴尬刚开始进入一个新环境,双方都属于一个认识对方的过程,尴尬瞬间是难免存在的。首先,你要接受尴尬,允许自己犯错,实习期本身就是来学习的,同事也不会期待你完美无缺。另外,不要太以自我为中心,其实你的尴尬瞬间也许没有人在意,是因你的对自己的关注而放大了不安全感。2.准备一些防止尴尬的话题和工作相关的,可以以请教的方式开启。比如:xx,这个表格我没有看懂,可以给我讲一下吗非工作的话题,可以聊聊中午吃什么、当地的天气如何、通勤远不远之类的。比如:附近有什么好吃的外卖吗?我刚来还不太熟悉3.每日练习,逐渐打...
sweep^0416:内向人,遇到好的领导很重要,我之前一段实习组里全e人就我一个i 刚入职第一周还会带着我聊一下,后面越来越冷落我,实在受不了,每天去到就想亖,mentor还要pua说是我融入不了集体(我真的以为是我的问题)后面我离职了,去了现在这一家公司,我的领导也是e人,但是我融入的很好,组里的人全都很好很好,也不会出现小团体什么的,所以说内向不是不融入环境的根本,就是公司跟带教的问题
点赞 评论 收藏
分享
ALEX_BLX:虽然说聊天记录不可信,不过这个趋势确实如此但我觉得也要想到一点就是卷后端的人里真正有“料”的人又有多少,我说的这个料都不是说一定要到大佬那种级别,而是就一个正常的水平。即使是现在也有很多人是跟风转码的,2-3个月速成后端技术栈的人数不胜数,但今时不同往日没可能靠速成进大厂了。这种情况就跟考研一样,你能上考场就已经打败一半的人了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务