HDU3461(並查集)

題目鏈接:點擊打開鏈接


解題思路:

一道看不出來是並查集的並查集題,做來做去還是覺得九野的題集不錯。題目大意就是有一個n位的密碼串,每位可能是a到z間的任意一個字母。m行輸入區間[ l , r],代表這個區間可以同時做+1操作,如果一組密碼通過有限次增加變成另一組密碼,那麼我們認爲這兩組密碼是相同的。求在m個區間下有多少種不同的密碼。

暴力來看是求26^n,當有cnt個不同區間加進來後,答案爲26^(n - cnt)。我們另 f 數組全部初始化爲-1,然後對於區間[ l , r ],我們用f[ l ] = r + 1來表示。每次操作,如果不存在區間[ l , r ],那麼cnt ++。

最後計算下26^(n - cnt)即可。


完整代碼:

#include <algorithm>
#include <iostream>
#include <cstring>
#include <climits>
#include <cstdio>
#include <string>
#include <cmath>
#include <map>
#include <queue>
using namespace std;
typedef long long LL;
const int MOD = int(1e9)+7;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-9;
const double PI = acos(-1.0); //M_PI;
int n , m;
const int maxn = 10000001;
int f[maxn];

int find(int x)
{
    return f[x] == -1 ? x : find(f[x]);
}

bool unin(int a , int b)
{
    int x = find(a);
    int y = find(b);
    if(x == y)  return false;
    f[x] = y;
    return true;

}

LL pow(int x)
{
    LL res = 1;
    for(int i = 0 ; i < x ; i ++)
    {
        res *= 26;
        res %= MOD;
    }
    return res;
}

int main()
{
    #ifdef DoubleQ
    freopen("in.txt","r",stdin);
    #endif
    while(cin >> n >> m)
    {
        memset(f , -1 , sizeof(f));
        int cnt = 0;
        int l , r;
        for(int i = 0 ; i < m ; i ++)
        {
            cin >> l >> r;
            if(unin(l , r + 1))
                cnt ++;
        }
        cout << pow(n - cnt) << endl;
    }
}


更多精彩:點擊打開鏈接

發佈了403 篇原創文章 · 獲贊 20 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章