>传送门<

题意:最初有 n个人且互不认识,接下来 m行,每行有 x,y表示xy交朋友,朋友关系满足自反性和传递性,每次输出当前选取4个人且互不认识的方案数。

思路:比赛的时候知道是用并查集做,然而也只是知道,具体的思维还没有想到这一块,还是太菜了,得去多做多想~

并查集合并操作可以理解为使得两个集合的人互相成为朋友,也就是两个集合并在了一起,答案是要求从所有人中挑出四个互相不是朋友的四个人,比较基础的组合数学知识,但因为每个集合的大小预先不知,所以变得难以计算。

假设我们现在算出了合并前的答案,在合并xy时,设 num[x]x所在集合的集合大小,num[y] 同理。考虑这两个集合对答案的贡献,有三种情况:

  1. x所在集合中取一个人,然后再从其他非y集合中挑选出三个互不在同一集合的人
  2. y所在集合中取一个人,然后再从其他非x集合中挑选出三个互不在同一集合的人
  3. x,y所在集合中各取一个人,然后再从其他集合中挑选出两个互不在同一集合的人

考虑合并之后

可以发现合并之后xy在同一集合,仔细观察上面说到的情况1、2,它们对答案的贡献并没有因为合并操作而改变。只有情况3,在合并之后,该贡献被消灭,所以要用上一次的答案减去这个情况,就是合并之后的答案

那么该怎么计算呢?情况3的答案等同于x,y所在集合中各取一个人的情况总数)*(从其他集合中挑选出两个互不在同一集合的人的情况总数

这两个集合中各选一个人的情况是很好求的:num[x]*num[y]。

好,现在就只剩下求从其他集合中挑选出两个互不在同一集合的人的情况总数,这一看就有点不好求,不要紧,我们开动脑瓜子想一想。

现在我们有两种做法,一种是直接求,一种是间接的求。

我们先来看直接求的那一种

我们假设K从所有集合中挑选出两个互不在同一集合的人的情况总数,那么我们用K减去从所有集合中挑选出两个互不在同一集合的人(其中至少有一个来自x或y),那么相减的结果不就是从其他集合中挑选出两个互不在同一集合的人的情况总数么,对不对,仔细想想肯定是这样的

那答案就出来了,如果x,y不需要合并的话(即在同一集合内),答案自然也就不需要更新,直接输出上一次的答案即可,其余部分按并查集处理就OK了

 Code

#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e5+; int n, m, x, y;
int f[maxn];
ll num[maxn];
ll K; //K表示从所有集合中挑选2个互不在同一集合的人的方案数
unsigned long long C; //C表示从所有集合中挑选4个互不在同一集合的人的方案数
int get(int x){
if (f[x]==x) return x;
return f[x]=get(f[x]);
}
void unite(int a,int b){
ll p = num[a]*num[b]; //从a, b所在集合中各取1个人的情况
ll q = num[a]*(n-num[a])+num[b]*(n-num[b])-num[a]*num[b]; //从所有集合挑选2个人(至少有一个来自a或b)的情况
ll k = K-q; //再从其他集合中挑选2个互不在同一集合的人
C -= p*k;
K = K-num[a]*num[b]; //由于a, b集合合并,K减去在同一集合中选2个人的方案
f[a] = b;
num[b] += num[a];
}
void init(){
C=1ull*n*(n-)/*(n-)/*(n-)/; //C初始化为从所有数中选4个的方案总数
K = 1ll*n*(n-)/; //K初始化从所有数中选2个的方案总数
for (int i = ; i <= n; i++) f[i] = i, num[i] = ;
}
int main()
{
scanf("%d%d", &n, &m);
init();
printf("%llu\n",C);
while(m--){
scanf("%d%d",&x,&y);
if (get(x)!=get(y))
unite(f[x],f[y]);
printf("%llu\n",C);
}
}

参考文章:
https://www.cnblogs.com/1625--H/p/11359772.html

2019牛客暑期多校训练营(第九场) E-All men are brothers(并查集+组合数学)的更多相关文章

  1. 2019牛客暑期多校训练营(第九场) D Knapsack Cryptosystem

    题目 题意: 给你n(最大36)个数,让你从这n个数里面找出来一些数,使这些数的和等于s(题目输入),用到的数输出1,没有用到的数输出0 例如:3  4 2 3 4 输出:0 0 1 题解: 认真想一 ...

  2. 2019牛客暑期多校训练营(第二场) H-Second Large Rectangle(单调栈)

    题意:给出由01组成的矩阵,求求全是1的次大子矩阵. 思路: 单调栈 全是1的最大子矩阵的变形,不能直接把所有的面积存起来然后排序取第二大的,因为次大子矩阵可能在最大子矩阵里面,比如: 1 0 0 1 ...

  3. 2019牛客暑期多校训练营(第五场)G - subsequeue 1 (一题我真的不会的题)

    layout: post title: 2019牛客暑期多校训练营(第五场)G - subsequeue 1 (一题我真的不会的题) author: "luowentaoaa" c ...

  4. 2019牛客暑期多校训练营(第九场)A:Power of Fibonacci(斐波拉契幂次和)

    题意:求Σfi^m%p. zoj上p是1e9+7,牛客是1e9:  对于这两个,分别有不同的做法. 前者利用公式,公式里面有sqrt(5),我们只需要二次剩余求即可.     后者mod=1e9,5才 ...

  5. [状态压缩,折半搜索] 2019牛客暑期多校训练营(第九场)Knapsack Cryptosystem

    链接:https://ac.nowcoder.com/acm/contest/889/D来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言52428 ...

  6. 2019牛客暑期多校训练营(第一场)A题【单调栈】(补题)

    链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 题目描述 Two arrays u and v each with m distinct elem ...

  7. 2019牛客暑期多校训练营(第一场) B Integration (数学)

    链接:https://ac.nowcoder.com/acm/contest/881/B 来源:牛客网 Integration 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 5242 ...

  8. 2019牛客暑期多校训练营(第一场) A Equivalent Prefixes ( st 表 + 二分+分治)

    链接:https://ac.nowcoder.com/acm/contest/881/A 来源:牛客网 Equivalent Prefixes 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/ ...

  9. 2019牛客暑期多校训练营(第二场)F.Partition problem

    链接:https://ac.nowcoder.com/acm/contest/882/F来源:牛客网 Given 2N people, you need to assign each of them ...

  10. 2019牛客暑期多校训练营(第八场)E.Explorer

    链接:https://ac.nowcoder.com/acm/contest/888/E来源:牛客网 Gromah and LZR have entered the fifth level. Unli ...

随机推荐

  1. Xbim.GLTF源码解析(二):IFC和GLTF的对应关系

    原创作者:flowell,转载请标明出处:https://www.cnblogs.com/flowell/p/10839179.html IFC IFC是建筑信息模型(BIM)数据开放的国际标准,在建 ...

  2. php curl 生成的cookie 文件含义 cookie 属性含义

    最近用了curl 感觉还是很方便的,看了下curl生成的 cookie 文件 格式 , 对其中一些值的含义不是很明白,去找了些cookie的资料看了下,做下备忘 PHP curl 生成 的 cooki ...

  3. Vue入坑第一篇

    写在前面的话:文章是个人学习过程中的总结,为方便以后回头在学习.文章中会参考官方文档和其他的一些文章,示例均为亲自编写和实践,若有写的不对的地方欢迎大家和我一起交流. 一.前言 本篇作为vue入门的一 ...

  4. idea 2019 1 spring boot 启动报错 An incompatible version [1.2.12] of the APR based Apache Tomcat Native library is installed, while Tomcat requires version [1.2.14]

    1.构建一个简单springboot工程,日志打印报错内容如下: 15:38:28.673 [main] DEBUG org.springframework.boot.devtools.setting ...

  5. winform 数据库资料导出Excel方法(适用于资料数据较多加载慢,不用呈现至DatagridView)

    Private Sub savefile(ByVal dgv2 As DataTable) Dim app As Object = CreateObject("Excel.Applicati ...

  6. 学习笔记33_EF跨数据库

    在App.Config中,可以: (1)自定义类 public xxxxDbContext() { public XXXXDbContext():base("name=xxxxContain ...

  7. 【原创】(十)Linux内存管理 - zoned page frame allocator - 5

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  8. 基本数据类型(While循环,For循环,列表以及相关用法)

    正常在没有学习循环情况下,我们要输出同样的语句,需要重复打印.相当重要!!!! While循环 将输出放在一行 end=""默认是换行 print("Hello Worl ...

  9. it公司比较

    1:本人西电通院2013届毕业硕士,根据今年找工作的情况以及身边同学的汇总,总结各大公司的待遇如下,吐血奉献给各位学弟学妹,公司比较全,你想去的公司不在这里面,基本上是无名小公司了:但无名小公司有时也 ...

  10. 决策树(上)-ID3、C4.5、CART

    参考资料(要是对于本文的理解不够透彻,必须将以下博客认知阅读,方可全面了解决策树): 1.https://zhuanlan.zhihu.com/p/85731206 2.https://zhuanla ...