トピックリンク:こちらをクリックしてください
質問の意味:
エントリー 長さを表します 列、 そこ表し、 ライン入力、次 行入力 表し 最初に 文字の真ん中 の数が偶数です。 表します 最初に 文字の真ん中 奇数です。もし 最初の文 矛盾の言葉で初めて正面、出力されます 。
アイデアの分析:
を表し 、でもこの状態にあります 表し 奇数の状態すなわち
同じです
- もし 奇数です、 奇数であります
- もし 偶数で、 偶数であります
不均一です
- もし 偶数で、 奇数であります
- もし 奇数です、 偶数であります
理解します:
サイドバンド権互いに素セット: と どのような関係があることはどのくらいの量に依存するように、彼らは同じコレクションであり、関連しています
互いに素セットの拡張フィールド:長い条件が真である限り、コレクションは、その後、残りのすべての条件が必然的に確立しました。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
const int N = 40010, base = N / 2;
int n, m;
int p[N];
map<int,int> mp;
int get(int x) // 在线离散化
{
if(mp.count(x) == 0) mp[x] = ++n;
return mp[x];
}
int find(int x)
{
if(x != p[x]) p[x] = find(p[x]);
return p[x];
}
int main()
{
scanf("%d%d", &n, &m);
n = 0; // 用于离散化
for(int i = 1; i < N; ++i) p[i] = i; // 初始化
int res = m;
for(int i = 1; i <= m; ++i)
{
int a, b;
char op[6];
scanf("%d%d%s", &a, &b, op);
if(res != m) continue;
a = get(a - 1), b = get(b);
if(op[0] == 'e') // 同类
{
if(find(a + base) == find(b)) // 有矛盾
{
res = i - 1;
break; // 数据没有输入完,可以break
}
p[find(a)] = find(b);
p[find(a + base)] = find(b + base);
}
else // 异类
{
if(find(a) == find(b)) // 有矛盾
{
res = i - 1;
break;
}
p[find(a)] = find(b + base);
p[find(a + base)] = find(b);
}
}
printf("%d\n", res);
return 0;
}