P1863 [Poetize I]黑魔法师之门
时间: 1000ms / 空间: 131072KiB / Java类名: Main
背景
经过了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行,表示每次操作后的密码。
测试样例1
输入
4 8
3 1
3 2
2 1
2 1
1 3
1 4
2 4
2 3
输出
0
0
1
3
7
7
15
31
备注
第三次添加之后,存在一个满足条件的子图 {1, 2, 3}(其中1, 2, 3是数据中【边】的标号)。
第四次添加之后,存在三个子图 {1, 2, 3},{1, 2, 4},{3, 4}。
……
对于30% 的数据,N, M≤10。
对于100% 的数据,N≤200000,M≤300000。
提醒:子图不一定连通。举另外一个例子,例如点(1、2、3),(4、5、6)分别组成一个三元环,则图中有三个所求子图。
分析一波后可以知道,每连一条边,如果两点之前已经连通,那么ans=ans*2+1
用并查集维护即可
但是!但是为什么TLE啊!该做的优化我都做了啊,为何会TLE啊!
----后记:TYVJ有毒,换成CODEVS秒过。辣鸡OJ站耗我时间毁我青春
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 int fa[200010]; 7 int n,m; 8 long long ans=0; 9 10 inline int read(){ 11 int x=0;char ch=getchar(); 12 while(ch<‘0‘||ch>‘9‘)ch=getchar(); 13 while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} 14 return x; 15 } 16 inline int find(int x){//并查集找父节点 17 if(fa[x]==x)return x; 18 else return fa[x]=find(fa[x]); 19 } 20 int main(){ 21 n=read();m=read(); 22 int i; 23 for(i=1;i<=n;i++)fa[i]=i; 24 for(i=1;i<=m;i++){ 25 int a=find(read()),b=find(read()); 26 if(a==b) 27 {ans=(ans<<1)+1; 28 if(ans>=1000000009)ans-=1000000009;} 29 else fa[b]=a; 30 printf("%lld\n",ans); 31 } 32 return 0; 33 }