链接:https://ac.nowcoder.com/acm/contest/889/E
来源:牛客网

Amy asks Mr. B problem E. Please help Mr. B to solve the following problem.

There are n people, who don’t know each other at the beginning.
There are m turns. In each turn, 2 of them will make friends with each other.
The friend relation is mutual and transitive.
If A is a friend of B, then B is also a friend of A.
For example, if A is a friend of B, B is a friend of C, then A and C are friends.
At the beginning and after each turn, please calculate the number of ways to select four people from, such that any two of these four are not friends.

输入描述:
The first line contains two integers, n and m (n <= 100000, m <= 200000), which are the number of people, and the number of turns.

In the following m lines, the i-th line contains two integers x and y ( 1 <= x <= n, 1 <= y <= n, x ≠ y), which means the x-th person and the y-th person make friends in the i-th turn.

The x-th person and y-th person might make friends in several turns.
输出描述:
Output m+1 lines, each line contains an integer, which is the number of quadruples.

Output at the beginning and after each turn, so there are m+1 lines.
示例1
输入
复制
6 6
1 2
3 4
4 5
3 5
3 6
2 4
输出
复制
15
9
4
0
0
0
0
示例2
输入
复制
100000 0
输出
复制
4166416671249975000
说明
Don’t use int.

官方题解如上。
这个题目解法不少,并查集+dp或者像题解这么做。个人认为题解这样算是比较好理解的。dp确实很简单,但是真的不好理解(dp算是一点不会吧)。
一开始我们能求出原始总共有多少种做法。合并两个集合之后,对原答案的贡献是多少?这是解题应该想的。
假设是第一次合并,合并两个集合之前,我们选四个人,可以直接c(n,4)来求解。
合并之后,减少了多少呢?在合并之前,我们可以在要合并的两个集合中各选出一个人,在从剩余的里面选出两个人,在剩余的里面选出两个人还需要减去在相同集合选出两个人的情况。这是这两个集合在合并前做的贡献,合并后就没有了。。那么我们在合并后就应该减去这一块值。这就是合并后的答案值。在剩余的人里面选出两个人,我们要减去相同集合里面选出两个人的情况,我们设一个变量sum记录一下,在一开始这个值为0,合并某两个集合后,对于sum来说,少了(size[t1](size[t1]-1)/2+(size[t2](size[t2]-1)/2))种情况(就是在这两个集合选出两个人的情况),但是多了这两个集合合并起来之后选出两个人的情况。这样想就很简单了。
代码如下:

#include<bits/stdc++.h>
#define ll long long
using namespace std;const int maxx=1e5+100;
int f[maxx];
ll size[maxx];
ll ans,sum;
ll n,m,k;int getf(int u)
{return u==f[u]?u:f[u]=getf(f[u]);
}
void merge(int u,int v)
{int t1=getf(u);int t2=getf(v);if(t1!=t2){ll sub=size[t1]+size[t2];//要合并的两个集合总数 sum-=(size[t1]*(size[t1]-1)/2+size[t2]*(size[t2]-1)/2);// 合并后对于sum减少了这些ll lose=size[t1]*size[t2]*((n-sub)*(n-sub-1)/2-sum);//合并两个集合对总数的贡献是减少了要合并的两个集合乘积再乘上剩下的人里面选出2个人 ans-=lose;sum+=sub*(sub-1)/2;//合并之后对sum增加了这些k--;//合并一次,集合数就减少一个,少于四个就直接输出零就行。f[t1]=t2;size[t2]+=size[t1];}printf("%lld\n",ans);
}
int main()
{int x,y;while(~scanf("%lld%lld",&n,&m)){for(int i=0;i<=n;i++) f[i]=i,size[i]=1;k=n;sum=ans=0;ans=n*(n-1)/2;ans*=(n-2);ans/=12;ans*=(n-3);printf("%lld\n",ans);while(m--){scanf("%d%d",&x,&y);if(k<4) printf("0\n");else merge(x,y);}}return 0;
}

努力加油a啊,(o)/~

All men are brothers(并查集+思维 好题!!!)相关推荐

  1. CodeForces - 468B Two Sets(并查集+思维)

    题目链接:点击查看 题目大意:现在给出两个集合A和B,再给出两个数a和b,现在规定在集合A中的数x必须满足x和a-x同时在集合a中,而在集合B中的数x也同样需要满足x和b-x同时在集合B中,现在给出一 ...

  2. gym:Problem A Artwork(并查集思维题)

    20162017-acmicpc-nordic-collegiate-programming-contest-ncpc-2016 Problem A Artwork 题目链接 http://codef ...

  3. 2020牛客暑期多校训练营(第八场)I-Interesting Computer Game(并查集 + 思维)

    链接: I-Interesting Computer Game 题意: 给出 n 组 a,b,每次可以选择 a 或者选择 b ,问做多可以选多少个不同的数. 思路: 考虑每个连通块 , 如果是 n 个 ...

  4. Codeforces 200A Cinema 并查集 + 思维 (看题解)

    Cinema 感觉这个题好神啊... 首先如果 n 比 m 大, 我们先旋转90度. 我们要加入一个(x, y)的时候, 我们枚举答案所在的行离 x 的距离 g , 然后对于x + g 行来说 我们找 ...

  5. upc 潜入苏拉玛 多源bfs + 并查集 + 思维

    潜入苏拉玛 时间限制: 1 Sec 内存限制: 128 MB 题目描述 你接到了⼀个任务,让你潜⼊苏拉玛城,和线⼈取得联络.苏拉玛的地图是⼀张N个点M条边的⽆向图,每个点表⽰苏拉玛城的⼀个路⼜,每条边 ...

  6. 小希的迷宫 HDU - 1272---并查集+思维

    上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走.但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就是说如果有一个通道连通了 ...

  7. P1892 [BOI2003]团伙 +食物链 POJ - 1182 (并查集+思维)

    思路①: 开数组enem[i]记录节点i的敌对节点,当再次输入i的敌对节点时就把他所在并查集的根节点和enem[i]并起来. #include<bits/stdc++.h> using n ...

  8. CodeForces - 123A prime permutation(并查集,水题)

    题目链接:点击查看 题目大意:给出一个字符串s,问能否通过重组其字母顺序,从而满足:若字符串下标从1开始,对于每一个质数下标,满足 题目分析:其实在纸上稍微写写画画就能看出个大概的规律,当字符串的长度 ...

  9. 【CSU - 1004】Xi and Bo(并查集,裸题)

    题干: Bo has been in Changsha for four years. However he spends most of his time staying his small dor ...

最新文章

  1. 《Docker容器:利用Kubernetes、Flannel、Cockpit和Atomic构建和部署》——2.2 容器式Linux系统的Docker配置...
  2. boost::python::ndarray相关的测试程序
  3. undolog 是binlog_msyql日志-binlog-undolog-redolog
  4. ie浏览器ip代理怎么设置
  5. 零基础能不能学习web前端开发?
  6. 使用Thrift让Python为Java提供服务
  7. Windows下 ffmpeg + labelImg 提取视频帧 得到图片集 并 标注图片 来 构造数据集
  8. 基于SpringBoot的后台管理系统(启动类解析,开源的世界真好)(一)
  9. 数据结构笔记(七)-- 顺序栈
  10. Matlab关联m文件与m文件关联设置
  11. foxmail 7.2密码查看工具_MacOS装机必备:Archiver 3 for Mac解压缩工具
  12. vscode插件之php插件koroFileHeader(自动生成注释)
  13. Linux 设备驱动--- 并发 与 竞态 --- atomic_t --- atomic_dec_and_test --- 原子操作
  14. esxi 命令行查看设备
  15. paip.提升用户体验---提高兼容性无JS支持总结
  16. 阿里程序员推荐的9款最佳编程字体?
  17. Android小技巧
  18. oracle weituxinxi,Oracle 语句记录
  19. 如何设计一个网络程序
  20. AMD CPU搞编程能行吗

热门文章

  1. Oracle代码块详解,Oracle可执行代码块
  2. pythonfor循环100次_【零基础学Python】For循环和RANGE()函数
  3. SQL注入-二阶注入(十)
  4. GHUnit for iOS测试指南
  5. java内存高水位_jvm(1)---java内存结构
  6. BFS,优先队列优化
  7. Codepen 每日精选(2018-3-30)
  8. Backbone.js源码解读(转载)
  9. maven+jenkins自动化构件
  10. Basic Calculator