输入的询问可能=0
巨坑…..因此re一晚上
令sum[j]=∑ji=0a[i] (mod2)
则若sum[a]=sum[b]且sum[b]=sum[c],则sum[a]=sum[b]=sum[c]具有传递性
于是便可分为2个集合,sum[x]=1和sum[y]=0
若[i,j]和为偶数,sum[j]−sum[i−1]=0 (mod 2)
find(i−1)==find(j)
若[i,j]和为奇数,sum[j]−sum[i−1]=1 (mod 2)
令maxVal=n
同时定义sum[x+maxVal]!=sum[x]
则若询问[i,j]和为奇数,则将j合并到集合i−1+maxVal表示i−1,j不在同一集合
#include<stdio.h>
#include<bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define MEM(a,x) memset(a,x,sizeof(a))
#define lowbit(x) ((x)&-(x))
using namespace std;
const int inf = 1e9+7;
const int N = 5e3 + 50;
const int M = 10*N+50;
char str[10];
struct data{
int s,t;
bool odd;
}ask[N];
int discr(int n){//离散化 返回最大值
map<int,int>mp;
for(int i=0;i<n;++i){
mp[ask[i].s]=0;
mp[ask[i].t]=0;
mp[ask[i].s-1]=0;
}
int j=1;
for(map<int,int>::iterator it=mp.begin();it!=mp.end();++it){
it->second=j++;
}
for(int i=0;i<n;++i){
ask[i].s=mp[ask[i].s];
ask[i].t=mp[ask[i].t];
}
return mp.empty()?1:mp.rbegin()->second;//若不判空集,询问为0时re
}
struct Union{//并查集
int par[M];
void init(int n){
for(int i=0;i<n;++i){
par[i]=i;
}
}
int find(int x){
return x==par[x]?x:(par[x]=find(par[x]));
}
void merge(int x,int y){
x=find(x);
y=find(y);
par[y]=x;
}
}un;
int slove(int n){
int maxVal=discr(n);
un.init(2*maxVal+1);
int ans=0;//可能询问为0,初始ans=0
for(int i=0;i<n;++i){
int x=ask[i].s-1;
int y=ask[i].t;
if(ask[i].odd){
if(un.find(x)==un.find(y)){
break;
}
else{
un.merge(x+maxVal,y);
un.merge(y+maxVal,x);
}
}
else{
if(un.find(x+maxVal)==un.find(y)){
break;
}
else{
un.merge(x,y);
un.merge(x+maxVal,y+maxVal);
}
}
ans=i+1;
}
return ans;
}
int main(){
//freopen("/home/lu/code/r.txt","r",stdin);
//freopen("/home/lu/code/w.txt","w",stdout);
int n,k;
while(~scanf("%d",&k)&&k!=-1){
scanf("%d",&n);
for(int i=0;i<n;++i){
scanf("%d%d%s",&ask[i].s,&ask[i].t,str);
ask[i].odd=(str[0]=='o');
}
printf("%d\n",slove(n));
}
return 0;
}