2019牛客暑期多校训练营(第九场) E All men are brothers
知识点:并查集+组合数学
并查集合并操作可以理解为使得两个集合的人互相成为朋友,也就是两个集合并在了一起,答案是要求从所有人中挑出四个互相不是朋友的四个人,比较基础的组合数学知识,但因为每个集合的大小预先不知,所以变得难以计算。
假设我们现在算出了合并前的答案,在合并x和y时,设 \(sz[x]\) 为\(x\)所在集合的集合大小,\(sz[y]\) 同理。考虑这两个集合对答案的贡献。有三种情况:
- 从x所在集合中取一个人,然后再从其他非y集合中挑选出三个互不在同一集合的人
- 从y所在集合中取一个人,然后再从其他非x集合中挑选出三个互不在同一集合的人
- 从x,y所在集合中各取一个人,然后再从其他集合中挑选出两个互不在同一集合的人
考虑合并之后
可以发现合并之后x和y在同一集合,仔细观察上面说到的情况1、2,它们对答案的贡献并没有因为合并操作而改变。只有情况3,在合并之后,该贡献被消灭,所以要用上一次的答案减去这个情况,就是合并之后的答案。
该怎么计算?情况3的答案等同于从非x,y的集合中挑两个集合并从这两个集合中各选一个人的情况总数。
举个例子,比如除去x,y所在的集合,剩下的集合的个数分别是
3 4 3 2
那么应该这么计算:
\((3*4 + 3*3 + 3 * 2) + (4*3+4*2) + (3*2)\)
等同于
\]
总人数为n,sum为每个集合大小的平方和,那么情况3的总数为
\]
然后 res -= num
更新答案即可
最后更新一下sum和 sz[x]
或sz[y]
(取决于用哪个作为所在集合代表元素)
res初始化为\(C_n^4\)
由于n 是1e5,所以对n分情况讨论求\(C_n^4\)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100010;
ll n,m;
ll fa[N],sz[N];
int find(int x){
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
int main(){
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++)fa[i] = i,sz[i] = 1ll;
if(n < 4){
printf("0\n");
while(m--){
int x,y;scanf("%d%d",&x,&y);
printf("0\n");
}
return 0;
}
ll res = 0;
if(n % 4 == 0){
res = n / 4 * (n-1) / 3 * (n-2) / 2 * (n-3);
}
else if(n % 4 == 1){
res = n * (n-1) / 4 * (n-2) / 3 * (n-3) / 2;
}
else if(n % 4 == 2){
res = n / 2 * (n-1) * (n-2) / 4 * (n-3) / 3;
}
else{
res = n / 3 * (n-1)/2 * (n-2) / 1 * (n-3)/4;
}
printf("%lld\n",res);
ll sum = n;
while(m--){
int x,y;
scanf("%d%d",&x,&y);
x = find(x);
y = find(y);
if(x == y){//如果已经在同一集合就不更新答案
printf("%lld\n",res);
continue;
}
sum -= sz[x] * sz[x];
sum -= sz[y] * sz[y];
res -= (sz[x] * sz[y]) * (((n - sz[x] - sz[y]) * (n - sz[x] - sz[y]) - sum)/2);
fa[x] = y;
sz[y] += sz[x];
sum += sz[y] * sz[y];
if(res < 0)res = 0;//res不能减成负数
printf("%lld\n",res);
}
return 0;
}
2019牛客暑期多校训练营(第九场) E All men are brothers的更多相关文章
- 2019牛客暑期多校训练营(第九场) D Knapsack Cryptosystem
题目 题意: 给你n(最大36)个数,让你从这n个数里面找出来一些数,使这些数的和等于s(题目输入),用到的数输出1,没有用到的数输出0 例如:3 4 2 3 4 输出:0 0 1 题解: 认真想一 ...
- 2019牛客暑期多校训练营(第二场) H-Second Large Rectangle(单调栈)
题意:给出由01组成的矩阵,求求全是1的次大子矩阵. 思路: 单调栈 全是1的最大子矩阵的变形,不能直接把所有的面积存起来然后排序取第二大的,因为次大子矩阵可能在最大子矩阵里面,比如: 1 0 0 1 ...
- 2019牛客暑期多校训练营(第五场)G - subsequeue 1 (一题我真的不会的题)
layout: post title: 2019牛客暑期多校训练营(第五场)G - subsequeue 1 (一题我真的不会的题) author: "luowentaoaa" c ...
- 2019牛客暑期多校训练营(第九场)A:Power of Fibonacci(斐波拉契幂次和)
题意:求Σfi^m%p. zoj上p是1e9+7,牛客是1e9: 对于这两个,分别有不同的做法. 前者利用公式,公式里面有sqrt(5),我们只需要二次剩余求即可. 后者mod=1e9,5才 ...
- [状态压缩,折半搜索] 2019牛客暑期多校训练营(第九场)Knapsack Cryptosystem
链接:https://ac.nowcoder.com/acm/contest/889/D来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言52428 ...
- 2019牛客暑期多校训练营(第一场)A题【单调栈】(补题)
链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 题目描述 Two arrays u and v each with m distinct elem ...
- 2019牛客暑期多校训练营(第一场) B Integration (数学)
链接:https://ac.nowcoder.com/acm/contest/881/B 来源:牛客网 Integration 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 5242 ...
- 2019牛客暑期多校训练营(第一场) A Equivalent Prefixes ( st 表 + 二分+分治)
链接:https://ac.nowcoder.com/acm/contest/881/A 来源:牛客网 Equivalent Prefixes 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/ ...
- 2019牛客暑期多校训练营(第二场)F.Partition problem
链接:https://ac.nowcoder.com/acm/contest/882/F来源:牛客网 Given 2N people, you need to assign each of them ...
- 2019牛客暑期多校训练营(第八场)E.Explorer
链接:https://ac.nowcoder.com/acm/contest/888/E来源:牛客网 Gromah and LZR have entered the fifth level. Unli ...
随机推荐
- 你编写的Java代码是咋跑起来的?
如果你是一名 Java 开发人员,你肯定指定 Java 代码有很多种不同的运行方式.比如说可以在开发工具(IDEA.Eclipse等)中运行,可以双击执行 jar 文件运行,也可以在命令行中运行,甚至 ...
- Fine-Grained(细粒度) Image – Papers, Codes and Datasets
Table of contents Introduction Survey papers Benchmark datasets Fine-grained image recognition Fine- ...
- Topshelf+Quartz在.Net Core框架下的实现
在我们日常开发工作中,经常会运用到Quartz+Topshelf组件的组合来开发一些定时任务.那么在.Net Core下如何去使用呢?我自己尝试搭建了一个测试项目,过程中遇到了以下一些问题: Quar ...
- Linux 命令之 crontab
crontab 简介 crontab 主要用于需要管理周期执行定时任务的场景 crontab 安装 (有些系统默认已经带了 crontab,无需安装的朋友可以直接跳过本节) 安装: yum insta ...
- Java面试官最爱问的volatile关键字
在Java的面试当中,面试官最爱问的就是volatile关键字相关的问题.经过多次面试之后,你是否思考过,为什么他们那么爱问volatile关键字相关的问题?而对于你,如果作为面试官,是否也会考虑采用 ...
- JNI技术实现--Java调C/C++
废话不多说,首先我们来看Java调用C/C++步骤: 1.编写Java代码,在代码中使用native关键字标明该方法是调用本地库,不需要实现. 2.使用javah -jni 命令,生成对应的头文件,此 ...
- 很详细很详细的gitLab使用具体流程
gitLab详细流程 先说一下整个流程,就是先建立一个项目-----拆分里程碑-----拆分issue----项目开发-----项目总结---关闭里程碑 下面是每个步骤具体的步骤,这个比较适合那种纯新 ...
- PyQt图形化布局
安装PyQt第三方库 pip install PyQt5 安装Qt Designer(Qt的布局工具) pip install PyQt5-tools PyChram设置Qt工具 配置Qt Desig ...
- RobotFramework自动化测试框架-Selenium Web自动化(二)关于在RobotFramework中如何使用Selenium很全的总结(上)
好久没有继续分享关于自动化测试相关的东西了,自动化在现今的测试领域已经越来越重要了,大部分公司在测试岗位招聘中都需要会相关的自动化测试知识.而 RobotFramework自动化测试框架 是自动化测试 ...
- 「2019.8.11 考试」一套把OI写的很诗意的题
这次写的更惨了,T2暴力再次挂掉了. 先写了T1的75暴力,然后写了T2的70分暴力(挂成了25),T3啥也不会骗了12分.T3看完题一点思路没有,心态爆炸了,一直在观察数据,忽略的思考的重要性,以至 ...