程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> POJ 1733 並查集 偏移向量

POJ 1733 並查集 偏移向量

編輯:C++入門知識

這題也是用到了偏移向量

一個由0,1組成的數字串~~,現在你問一個人一些問題,第i位到第j位的1的個數為奇數還是偶數。他會告訴你答案, 但是答案可能會自相矛盾,現在就是最多能有前幾個回答是不矛盾的。


設r[i]表示第1位到第i位的1個數的奇偶狀況,r[i] = 0表示有偶數個1,r[i] = 1表示有奇數個1。
那麼要是第i位到第j位為偶數個1時,r[i-1] = 1, r[j] = 1 或r[i-1] = 0, r[j] = 0 所以 r[i-1] ^ r[j] = 0
要是為奇數個1時,r[i-1] = 1, r[j] = 0 或 r[i-1] = 0, r[j] = 1所以r[i-1] ^ r[j] = 1


那麼我們可以使用並查集,用一個數組d[i]代表r[i]與其祖先的異或值

如果回答的兩個區間的端點以前都出現過,那麼就判斷異或值是否與以前的那個相等

如果沒出現過,就直接合並,更新異或值


[cpp]
#include <iostream>  
#include <vector>  
#include <map>  
#include <set>  
#include <queue>  
#include <stack>  
#include <algorithm>  
#include <cstdio>  
#include <cstdlib>  
#include <string>  
#include <cstring>  
#include <cmath>  
#define MAXN 22222  
#define MAXM 55555  
#define INF 100000000  
using namespace std; 
int n, m; 
int fa[MAXN]; 
int l[MAXN], r[MAXN], c[MAXN]; 
int x[MAXN], d[MAXN]; 
int find(int x) 

    if(fa[x] == x) return x; 
    int t = find(fa[x]); 
    d[x] ^= d[fa[x]]; 
    fa[x] = t; 
    return t; 

bool join(int x, int y, int v) 

    int fx = find(x); 
    int fy = find(y); 
    if(fx == fy) return ((d[x] ^ d[y]) == v); 
    else 
    { 
        fa[fx] = fy; 
        d[fx] = d[x] ^ d[y] ^ v; 
        return 1; 
    } 

int bin(int low, int high, int v) 

    while(low <= high) 
    { 
        int mid = (low + high) >> 1; 
        if(x[mid] == v) return mid; 
        else if(x[mid] > v) high = mid - 1; 
        else low = mid + 1; 
    } 
    return -1; 

int main() 

    char s[15]; 
    scanf("%d%d", &n, &m); 
    int cnt = 0; 
    for(int i = 1; i <= m; i++) 
    { 
        scanf("%d%d%s", &l[i], &r[i], s); 
        x[cnt++] = l[i] - 1; 
        x[cnt++] = r[i]; 
        if(s[0] == 'e') c[i] = 0; 
        else c[i] = 1; 
    } 
    sort(x, x + cnt); 
    cnt = unique(x, x + cnt) - x; 
    for(int i = 1; i < MAXN; i++) fa[i] = i, d[i] = 0; 
    int fg = 0; 
    for(int i = 1; i <= m; i++) 
    { 
        int L = bin(0, cnt - 1, l[i] - 1) + 1; 
        int R = bin(0, cnt - 1, r[i]) + 1; 
        if(!join(L, R, c[i])) 
        { 
            fg = 1; 
            printf("%d\n", i - 1); 
            break; 
        } 
    } 
    if(!fg) printf("%d\n", m); 
    return 0; 

#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cstring>
#include <cmath>
#define MAXN 22222
#define MAXM 55555
#define INF 100000000
using namespace std;
int n, m;
int fa[MAXN];
int l[MAXN], r[MAXN], c[MAXN];
int x[MAXN], d[MAXN];
int find(int x)
{
    if(fa[x] == x) return x;
    int t = find(fa[x]);
    d[x] ^= d[fa[x]];
    fa[x] = t;
    return t;
}
bool join(int x, int y, int v)
{
    int fx = find(x);
    int fy = find(y);
    if(fx == fy) return ((d[x] ^ d[y]) == v);
    else
    {
        fa[fx] = fy;
        d[fx] = d[x] ^ d[y] ^ v;
        return 1;
    }
}
int bin(int low, int high, int v)
{
    while(low <= high)
    {
        int mid = (low + high) >> 1;
        if(x[mid] == v) return mid;
        else if(x[mid] > v) high = mid - 1;
        else low = mid + 1;
    }
    return -1;
}
int main()
{
    char s[15];
    scanf("%d%d", &n, &m);
    int cnt = 0;
    for(int i = 1; i <= m; i++)
    {
        scanf("%d%d%s", &l[i], &r[i], s);
        x[cnt++] = l[i] - 1;
        x[cnt++] = r[i];
        if(s[0] == 'e') c[i] = 0;
        else c[i] = 1;
    }
    sort(x, x + cnt);
    cnt = unique(x, x + cnt) - x;
    for(int i = 1; i < MAXN; i++) fa[i] = i, d[i] = 0;
    int fg = 0;
    for(int i = 1; i <= m; i++)
    {
        int L = bin(0, cnt - 1, l[i] - 1) + 1;
        int R = bin(0, cnt - 1, r[i]) + 1;
        if(!join(L, R, c[i]))
        {
            fg = 1;
            printf("%d\n", i - 1);
            break;
        }
    }
    if(!fg) printf("%d\n", m);
    return 0;
}


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved