cf1040E. Network Safety(并查集)
题意
一张图,n个点,m条边,每个点有个权值x,x<=1e18。如果一条边的两个端点不一样,那么这条边是安全的,开始时所有边都是安全的。
现在有一个病毒y,病毒可以入侵任意的点,入侵一个点后的权值为(y^x)。
(S,y)表示病毒的权值为y,它只入侵了点集S中的点,整张图的边都是安全的。求出所有的(S,y)。
Sol
不算是特别难想的div2压轴题。。
题目中保证了任意两个节点互不相同,因此想让图不安全,对于$(A, x)$一定是存在 A内一点 ^ x = 与该点相邻点的权值
显然,对于每一条边我们可以求出对应的x。
刚开始我傻乎乎的以为任意两个节点之间对应的值都是不同的,但是这样肯定是错的
比如 101 ^ 1 = 100, 1011 ^ 1 = 1010
但就算有相同的也没关系。
考虑$x$的贡献,如果存在两个节点,假设其权值分别为a,b,满足a ^ x = b
那么该节点要么同时不出现,要么同时出现,也就相当于把这两个点看成了一个点
然后我在这里又掉了一次坑,题目中只是说了“刚开始是安全的”,我天真的以为是互不相同。。
这样的话,就有可能存在好多个点看成一个点的情况,直接用并查集维护即可
最终的答案 = $\sum_{k} 2^siz(k) + (2^k - cnt) * (2^n)$
cnt表示互不相同的x的数量
$siz(k)$表示把$x ^ k = y$的点全都缩起来后的总点数
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#include<vector>
#define Pair pair<int, int>
#define MP(x, y) make_pair(x, y)
#define fi first
#define se second
#define LL long long
using namespace std;
const int MAXN = 1e6 + , mod = 1e9 + ;
inline LL read() {
char c = getchar(); LL x = , f = ;
while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * f;
}
int N, M, fa[MAXN];
LL po[MAXN], c[MAXN], K;
map<LL, vector<Pair> >mp;
int find(int x) {
return fa[x] == x ? fa[x] : fa[x] = find(fa[x]);
}
main() {
N = read(); M = read(); K = read();
po[] = ;
for(int i = ; i <= N; i++) c[i] = read();
for(int i = ; i <= max((LL)N, K); i++) po[i] = (1ll * * po[i - ]) % mod;
for(int i = ; i <= M; i++) {
int x = read(), y = read();
mp[c[x] ^ c[y]].push_back(MP(x, y));
}
LL ans = ;
map<LL, vector<Pair> >::iterator it;
for(int i = ; i <= N; i++) fa[i] = i;
for(it = mp.begin(); it != mp.end(); it++) {
LL val = it -> first;
vector<Pair> now = it -> second;
vector<int> res;
for(int i = ; i < now.size(); i++) {
int fx = find(now[i].fi), fy = find(now[i].se);
res.push_back(fx); res.push_back(fy);
if(fx == fy) continue;
fa[fx] = fy;
}
for(int i = ; i < res.size(); i++) fa[res[i]] = res[i];
(ans += po[tot]) %= mod;
}
printf("%I64d", (ans + 1ll * (po[K] - mp.size()) * po[N] % mod) % mod);
return ;
}
cf1040E. Network Safety(并查集)的更多相关文章
- POJ 2236 Wireless Network(并查集)
传送门 Wireless Network Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 24513 Accepted ...
- poj 2236:Wireless Network(并查集,提高题)
Wireless Network Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 16065 Accepted: 677 ...
- POJ 2236 Wireless Network (并查集)
Wireless Network 题目链接: http://acm.hust.edu.cn/vjudge/contest/123393#problem/A Description An earthqu ...
- POJ 2236:Wireless Network(并查集)
Wireless Network Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 36363 Accepted: 150 ...
- POJ3694:Network(并查集+缩点+lca)
Network Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 13172 Accepted: 4774 题目链接:htt ...
- Brain Network (easy)(并查集水题)
G - Brain Network (easy) Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & ...
- 【POJ - 2236】Wireless Network (并查集)
Wireless Network 这接翻译了 Descriptions 地震发生在东南亚.ACM(亚洲合作医疗团队)已经与膝上电脑建立了无线网络,但是一次意外的余震袭击,网络中的所有计算机都被打破了. ...
- Codeforces1023F Mobile Phone Network 【并查集】【最小生成树】
题目大意: 给一些没安排权值的边和安排了权值的边,没被安排的边全要被选入最小生成树,问你最大能把它们的权值和安排成多少.题目分析:假设建好了树,那么树边与剩下的每一条边都能构成一个环,并且非树边的权值 ...
- POJ3694 Network - Tarjan + 并查集
Description 给定$N$个点和 $M$条边的无向联通图, 有$Q$ 次操作, 连接两个点的边, 问每次操作后的图中有几个桥 Solution 首先Tarjan找出边双联通分量, 每个双联通分 ...
随机推荐
- mkfs在特定的分区上建立 linux 文件系统
Linux mkfs命令用于在特定的分区上建立 linux 文件系统 使用方式 : mkfs [-V] [-t fstype] [fs-options] filesys [blocks]参数 : ...
- PCLVisualizer可视化类(5)
博客转载自:http://www.pclcn.org/study/shownews.php?lang=cn&id=171 自定义交互 多数情况下,默认的鼠标和键盘交互设置不能满足用户的需求,用 ...
- 通过命令查看jboss的错误日志文件
链接jboss: ssh ip -l jboss
- Sharepoint2013商务智能学习笔记之Secure Store Service服务配置(二)
Secure Store Service 是运行在应用程序服务器上的授权服务,它提供一个存储用户凭据的数据库,Secure Store Service 在商务智能中的地位很重要,Sharepoint商 ...
- redis集群搭建踩坑笔记
推荐参考教程:https://blog.csdn.net/pucao_cug/article/details/69250101 错误: from /usr/lib/ruby/2.3.0/rubygem ...
- EIP权限工作流平台总结-4跨域配置
1.预览地址:www.eipflow.com (1) 权限工作流:www.demo.eipflow.com/Account/Login (2) 基础权限版:www.auth.eipflow.com/A ...
- [java基础]short s1 = 1; s1 = s1 + 1;有什么错?short s1 = 1; s1 += 1;有什么错?
为什么写这篇文章是因为搜到的答案里并没有阐明s1 = s1 + 1为什么就要转换为int类型. 由一下实验可知: public class test { public static void main ...
- JavaScript -- 常用的日期对象和数学对象
创建一个时间对象 var time=new Date(); //当前时间,()内可写入字符串 ,如'2017-10-10',可转为响应的时间 常用方法 time.getFullYear(); //从 ...
- UPCOJ9526(SG函数打表,nim游戏异或规则)
#include<bits/stdc++.h>using namespace std;int f[1007],SG[1007],S[1007];//f为可以选取的石头个数,SG为sg函数, ...
- Bloomberg 专线配置问题
其实很简单,满足bbg的要求就可以了, 配置如下几个网段的路由: 208.134.161.0 using the subnet mask of 255.255.255.0 205.183.246.0 ...