1. 程式人生 > 其它 >poj 1733 帶權並查集+離散化(lower_bound或者二分)

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); }