手写离散化
实际上,很多评测平台是会卡map的代码的,所以我们可以利用手写离散化来解决这个问题喵。
同时的,我们维护两个区间之间的关系时,奇数为1,偶数为0,这样以来,利用亦或运算。
如果两个节点亦或和为1,说明之间肯定不是成对出现的奇数或偶数,则区间关系为奇数
反之亦然
需要注意的是,我们维护的是区间之间的关系而不是两个数之间的
C++ 代码
#include<bits/stdc++.h>
using namespace std;
const int N=10010;
int n,m;
int a[N],fa[N],d[N],t;
struct question
{
int l,r,ans;
}que[N];
void read_discrete()
{
cin >> n >> m;
for(int i=1;i<=m;i++)
{
char str[5];
cin >> que[i].l >> que[i].r >> str;
que[i].ans=(str[0]=='o' ? 1 : 0);//是奇数为1,偶数为0
//那确实,相同xor为0,不相同xor为1
a[++t] = que[i].l-1;//离散化
a[++t] = que[i].r;
//之后要通过前缀和查询s[l-1]和 s[r]所以离散化这两个值
}
sort(a+1,a+t+1);
n=unique(a+1,a+t+1)-a-1;
//去重之后返回最后一个不重的数据的下一个位置,
//所以我们减去数组之后再减去1
}
int find(int x)
{
if(fa[x]!=x)
{
int t=find(fa[x]);
d[x]=d[x]^d[fa[x]];
fa[x]=t;
}
return fa[x];
}
int main()
{
read_discrete();
for(int i=1;i<=n;i++)
{
fa[i]=i;//并查集初始化
}
for(int i=1;i<=m;i++)
{
int x=lower_bound(a+1,a+n+1,que[i].l -1 ) - a;
int y=lower_bound(a+1,a+n+1,que[i].r) - a;
//存哈希表的时候是l-1和r,找也是找这两个值
//之后操作时,利用其下标来代表这个数进行一系列操作
int px=find(x);
int py=find(y);
//找根节点同时路径压缩算距离
if(px==py)
{
if( (d[x]^d[y]) != que[i].ans)
//和说的不一样(和之前有矛盾)
{
cout << i-1 << endl;
return 0;
}
}
else
{
fa[px]=py;
d[px]=d[x] ^ d[y] ^ que[i].ans;
}
}
cout << m << endl;
return 0;
}