poj 1733 带权并查集+离散化(lower_bound或者二分)
这题和kuangbin并查集专题的“how many answer are long”思想神似
但要离散化
#
离散化后,总数也变了,写程序时没有变过来,造成re,找了半小时
#
unique的用法是(a+1,a+1+len)-(a+1),类似于sort;
如果不打二分的话,lowerbound应该这么用:
g[i].r=lower_bound(lisan+1,lisan+1+len,g[i].r)-lisan;
注意这里后面-lisan的时候不是-(lisan+1);
#
l--是必须的,这个多玩几个数字就好了。
#
二分的模板:
while(l<r)
{
int mid=(l+r)/2;
if(lisan[mid]>=x)
{
r=mid;
}
else
{
l=mid+1;
}
}
#include <iostream> #include <math.h> #include <string.h> #include <vector> #include <map> #include <queue> #include <stdio.h> #include <algorithm> #include <cstdio> using namespace std; const int maxn=1e6; struct node{ int l,r,type; }g[maxn]; int n,t,cnt=0,relation[maxn],fa[maxn],len,lisan[maxn]; int find(int x) { if(fa[x]!=x) { int tmp=fa[x]; fa[x]=find(fa[x]); relation[x]=(relation[x]+relation[tmp])%2; } return fa[x]; } void pre(int len) { for(int i=1;i<=len;i++) { relation[i]=0; fa[i]=i; } } int ls(int x) { int l=1,r=len; while(l<r) { int mid=(l+r)/2; if(lisan[mid]>=x) { r=mid; } else { l=mid+1; } } return l; } int main( ) { /* 10 5 1 2 even 3 4 odd 5 6 even 1 6 even 7 10 odd*/ //freopen("lys.in","r",stdin); cin>>n>>t; for(int i=1;i<=t;i++) { int a,b; char c[10]; scanf("%d%d",&a,&b); cin>>c; g[i].l=a;g[i].r=b; if(c[0]=='e') g[i].type=0; else g[i].type=1; } for(int i=1;i<=t;i++) { cnt++; lisan[cnt]=g[i].r; cnt++; lisan[cnt]=g[i].l; } sort(lisan+1,lisan+cnt+1); len=unique(lisan+1,lisan+1+cnt)-(lisan+1); for(int i=1;i<=t;i++) { g[i].r=ls(g[i].r); g[i].l=ls(g[i].l); //printf("%d %d %d\n",i,g[i].l,g[i].r); } pre(len); for(int i=1;i<=t;i++) { int l=g[i].l-1,r=g[i].r; int f1,f2; f1=find(l),f2=find(r); if(f1==f2) { int ans; ans=(relation[l]+relation[r])%2; if(ans!=g[i].type) { printf("%d",i-1); return 0; } } else { fa[f1]=f2; relation[f1]=(relation[l]+relation[r]+g[i].type)%2; } } printf("%d",t); }