【SSL】1227 &【洛谷】P5937A Parity game

【SSL】1227 &【洛谷】P5937A Parity game

Time Limit:1000MS
Memory Limit:65536K

Title description

Alice and Bob are playing a game: he writes a sequence of 0 and 1. Alice chooses one of the paragraphs (for example, the 3rd to the 5th) and asks him whether there are odd 1s or even 1s in this paragraph. Bob answers your question, and Alice continues to ask. Alice wants to check Bob's answer and points out that there must be a problem with Bob's first answer. A question means that there is a 01 sequence that satisfies all the answers before this answer, and there is no sequence that satisfies all the answers before this answer and this answer.

Input format

The first line is an integer n, which is the length of the 01 sequence.

In line 2, an integer m is the number of questions and answers.

The third line starts with the question and the answer. Each line has two integers, which indicate the beginning and end of the segment you are asking about. Then Bob's answer. Odd means that there are an odd number of ones, and even means that there are even number of ones.

Output format

Output one line with a number x, indicating that there is a 01 sequence that satisfies the 1st to xth answers, but there is no sequence that satisfies the 1st to x+1th answers. If all answers are ok, you will output the number of all answers.

Sample input and output

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

Instructions/tips

For 100% data, 1 ≤ n ≤ 1 0 9, m ≤ 5 × 1 0 3 1 \le n \leq 10^9, m \leq 5 \times 10^31n109m5×103

Ideas

And check the extended domain,
n, n itself, domains with the same parity
n+tot, domains with different parity
Sort, remove duplication and save space.
Edge odd: x-1 and y have different parity, f[find(x-1)]=find(y+tot); f[find(x-1+tot)]=find(y);
Even number of sides: x-1 and y have the same parity, f[find(x-1)]=find(y); f[find(x-1+tot)]=find(y+tot);

It is definitely impossible to start from the entire 01 sequence, because its length is as high as 109.
Start with a relatively small n. In other words, we need to perform some special processing on the information.
ab even/odd, then point element b to a-1, and the weight of the edge is even/odd.
Let's illustrate this processing method by an example.
Insert picture description here

Obviously when the fourth message is added, there is already a value from 6 to 0, that is, (0+1+0) mod 2=1. At this time, adding 6 to 0 is obviously wrong.
It is not necessary to open an array of 1-109 when implementing it, because there are at most 104 different elements, so open a list to store the elements.
The general framework of the algorithm is to continuously use the above methods to process the read information, and the recursive nature of the interval can be used to determine whether it is contradictory or not.
The implementation of the above algorithm uses the union search set.

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int f[10010]/*n,n本身,奇偶性相同的域,n+tot,奇偶性不同的域*/,a[10010],tot=0;
struct jgt
{
    
    
	int x,y,w;
}b[5010];
int find(int x)//找代表值 
{
    
    
	if(f[x]==x) return x;
	return f[x]=find(f[x]);
}
int effind(int x)//二分查找 
{
    
    
	int l,r,mid;
	for(l=1,r=tot;l<r;)
	{
    
    
		mid=(l+r)/2;
		if(x>a[mid]) l=mid+1;
		else r=mid;
	}
	return r;
}
int main()
{
    
    
	char str[10];
	int n,m,j,i,t,x,y,ans=0;
	scanf("%d%d",&n,&m);
	for(i=1;i<=m;i++)
	{
    
    
		scanf("%d%d%s",&b[i].x,&b[i].y,&str);
		b[i].x--; 
		b[i].w=(str[0]=='o');
		a[++tot]=b[i].x;
		a[++tot]=b[i].y;
	}
	sort(a+1,a+1+tot);//排序 
	for(i=2,j=1;i<=tot;i++)//去重,节约空间 
		if(a[i]!=a[i-1])
			a[++j]=a[i];
	tot=j;
	for(i=1;i<=2*tot;f[i]=i,i++);//初始化
	for(i=1;i<=m;i++)
	{
    
    
		x=effind(b[i].x),y=effind(b[i].y);
		if(b[i].w)//奇数 
		{
    
    
			if(find(x)==find(y))
			{
    
    
				printf("%d",i-1);
				return 0;
			}
			else f[find(x)]=find(y+tot),f[find(x+tot)]=find(y);//合并 
		}
		else//偶数 
		{
    
    
			if(find(x)==find(y+tot))
			{
    
    
				printf("%d",i-1);
				return 0;
			}
			else f[find(x)]=find(y),f[find(x+tot)]=find(y+tot);//合并 
		}
	}
	printf("%d",m);
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_46975572/article/details/113004259