1. 程式人生 > >【NOIP2013模擬】黑魔法師之門

【NOIP2013模擬】黑魔法師之門

題目描述

經過了16個工作日的緊張忙碌,未來的人類終於收集到了足夠的能源。然而在與Violet星球的戰爭中,由於Z副官的愚蠢,地球的領袖applepi被邪惡的黑魔法師Vani囚禁在了Violet星球。為了重啟Nescafé這一巨集偉的科技工程,人類派出了一支由XLk、Poet_shy和lydrainbowcat三人組成的精英隊伍,穿越時空隧道,去往Violet星球拯救領袖applepi。

applepi被囚禁的地點只有一扇門,當地人稱它為“黑魔法師之門”。這扇門上畫著一張無向無權圖,而開啟這扇門的密碼就是圖中每個點的度數大於零且都是偶數的子圖的個數對1000000009取模的值。此處子圖 (V, E) 定義為:點集V和邊集E都是原圖的任意子集,其中E中的邊的端點都在V中。

但是Vani認為這樣的密碼過於簡單,因此門上的圖是動態的。起初圖中只有N個頂點而沒有邊。Vani建造的門控系統共操作M次,每次往圖中新增一條邊。你必須在每次操作後都填寫正確的密碼,才能夠開啟黑魔法師的牢獄,去拯救偉大的領袖applepi。

輸入

第一行包含兩個整數N和M。
接下來M行,每行兩個整數A和B,代表門控系統添加了一條無向邊 (A, B)。

輸出

輸出一共M行,表示每次操作後的密碼。

思路

這道題看上去很玄學,事實上其實很玄學。其實我們不用那麼複雜去想,就仨字:病——差——集。每次讀入兩個點,判斷他們的祖先(曾曾曾曾曾曾曾~祖父)是否相同,不相同就硬扯上關係(關係戶)(其實就改祖先,說那麼複雜幹啥子),相同——都是一家人,一起做點貢獻,ans=ans*2+1。

#include<cstdio>
#define NMA 200001
using namespace std;
long long f[NMA],n,m,e,r,a,b,ans;
int i;
int getfather(int x)
{
    if (f[x]==0) return x;else 
    {
        f[x]=getfather(f[x]);
        return f[x];
    }
}
int main()
{
    freopen("a.in","r",stdin);
    scanf("%lld%lld",&n,&m);
    for
(i=1;i<=m;i++) { scanf("%lld%lld",&a,&b); e=getfather(a); r=getfather(b); if (e!=r) { f[e]=r; }else ans=(ans*2+1)%1000000009; printf("%lld\n",ans); } }