Codechef TAPAIR Counting the important pairs 随机化、树上差分
题意:给出一个$N$个点、$M$条边的无向连通图,求有多少组无序数对$(i,j)$满足:割掉第$i$条边与第$j$条边之后,图变为不连通。$N \leq 10^5 , M \leq 3 \times 10^5$
竟然随机化,歪果仁的思想好灵活qwq肯定是数据结构做多了
看起来很像割边,考虑$tarjan$,但是边三连通分量并不是很好实现,而且有很多特殊情况需要判断,所以我们考虑另外的算法
考虑$tarjan$时建出的一棵树。对于它来说,在一个端点在其下方、另一个端点在其上方的的返祖边可以成为它的依靠,因为割掉它,这一条依靠边可以代替它的功能。而对于一条返祖边来说,割掉对于树边是没有影响的,我们就定义它自己为自己的依靠。
这样每一条边都有自己的依靠集合。考虑两条依赖集合相同的边,将它们割掉之后,中间一段的点就会因为上下都没有额外的依靠而使得图不连通。而对于一条依赖集合为空的边(即割边),它选择任何边都可以加入贡献。
所以我们现在需要考虑如何给某一段边加入贡献。然后CC的题解给出的玄学办法是:随机化+树上差分+XOR
我们考虑将给一条返祖边定权值为一个$random$出来的值$t$,然后把所有依靠它的边的依靠集合异或上这个值,这个可以树上差分去做。这样所有的依靠集合就变成了一个数。然后我们判断两条边的依靠集合对应的数是否相等即可。
Because 2^64 is large enough comparing to the range of N and M, don't worry about the probability. :) You will get AC if you implemented correctly.——原题题解
然而我$rand() WA$了好几发qwq
如果随机数种子出了问题的话就看下面这种玄学rand好了
#include<bits/stdc++.h>
#define CC
using namespace std; inline int read(){
int a = ;
bool f = ;
char c = getchar();
while(c != EOF && !isdigit(c)){
if(c == '-')
f = ;
c = getchar();
}
while(c != EOF && isdigit(c)){
a = (a << ) + (a << ) + (c ^ '');
c = getchar();
}
return f ? -a : a;
} const int MAXN = ;
struct Edge{
int end , upEd;
}Ed[MAXN * ];
int head[MAXN] , num[MAXN] , dep[MAXN] , fa[MAXN] , N , cntEd , cnt;
unsigned long long point[MAXN] , forS[MAXN * ];
bool vis[MAXN]; #define ll unsigned long long
inline ll rp(){return (1ll*rand())^(1ll*rand())<<^(1ll*rand())<<^(1ll*rand())<<^(1ll*rand())<<;} inline void addEd(int a , int b){
Ed[++cntEd].end = b;
Ed[cntEd].upEd = head[a];
head[a] = cntEd;
} void dfs1(int x , int t){
fa[x] = t;
dep[x] = dep[fa[x]] + ;
vis[x] = ;
for(int i = head[x] ; i ; i = Ed[i].upEd)
if(!vis[Ed[i].end])
dfs1(Ed[i].end , x);
else
if(dep[Ed[i].end] > dep[x]){
long long t = rp();
point[x] ^= t;
point[Ed[i].end] ^= t;
forS[++cnt] = t;
}
} void dfs2(int x){
for(int i = head[x] ; i ; i = Ed[i].upEd)
if(fa[Ed[i].end] == x){
dfs2(Ed[i].end);
point[x] ^= point[Ed[i].end];
}
if(x != )
forS[++cnt] = point[x];
} int main(){
#ifdef CC
freopen("TAPAIR.in" , "r" , stdin);
freopen("TAPAIR.out" , "w" , stdout);
#endif N = read();
int M = read();
for(int i = ; i <= M ; i++){
int a = read() , b = read();
addEd(a , b);
addEd(b , a);
}
dfs1( , );
dfs2();
sort(forS + , forS + cnt + );
int p = ;
while(p <= cnt && forS[p] == )
p++;
long long ans = (p - ) * (long long)(p - ) / + (p - ) * (M - p + );
while(p <= cnt){
int beg = p;
while(p <= cnt && forS[p] == forS[beg])
p++;
ans += (long long)(p - beg) * (p - beg - ) / ;
}
cout << ans;
return ;
}
Codechef TAPAIR Counting the important pairs 随机化、树上差分的更多相关文章
- Counting The Important Pairs CodeChef - TAPAIR
https://vjudge.net/problem/CodeChef-TAPAIR 合法的删除方法: 第一种:桥边与其余任意边(1)桥*(桥-1)/2(两条桥边)(2)桥*(m-桥)(桥边+其他边) ...
- BZOJ3569 DZY Loves Chinese II(随机化+树上差分+线性基)
上一题的强制在线版.对图跑出一个dfs树,给非树边赋上随机权值,树边的权值为覆盖他的非树边权值的异或.这样如果某条树边和覆盖他的非树边都被割掉(即图不连通),他们的异或值就为0.每次对询问看有没有子集 ...
- Codechef Sad Pairs——圆方树+虚树+树上差分
SADPAIRS 删点不连通,点双,圆方树 非割点:没有影响 割点:子树DP一下 有不同颜色,所以建立虚树 在圆方树上dfs时候 如果当前点是割点 1.统计当前颜色虚树上的不连通点对,树形DP即可 2 ...
- [luogu P3128][USACO15DEC]Max Flow [LCA][树上差分]
题目描述 Farmer John has installed a new system of pipes to transport milk between the stalls in his b ...
- P3128 [USACO15DEC]最大流Max Flow(LCA+树上差分)
P3128 [USACO15DEC]最大流Max Flow 题目描述 Farmer John has installed a new system of pipes to transport mil ...
- [USACO15DEC]最大流Max Flow(树上差分)
题目描述: Farmer John has installed a new system of N−1N-1N−1 pipes to transport milk between the NNN st ...
- P3128 [USACO15DEC]最大流Max Flow (树上差分)
题目描述 Farmer John has installed a new system of N-1N−1 pipes to transport milk between the NN stalls ...
- 【BZOJ-4326】运输计划 树链剖分 + 树上差分 + 二分
4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 703 Solved: 461[Submit][Status] ...
- 树上差分 (瞎bb) [树上差分][LCA]
做noip2015的运输计划写了好久好久写不出来 QwQ 于是先来瞎bb一下树上差分 混积分 树上差分有2个常用的功能: (1)记录从点i到i的父亲这条路径走过几次 (2)将每条路径(s,t ...
随机推荐
- 【读书笔记】iOS-UDID
UIDevice类可以返回当前iOS设备的UDID,以前开发者通常使用UDID作为识别每台设备的唯一标识,然后从iOS5开始,苹果公司将这一功能标记为废止并不推荐使用,苹果公司在iOS6之后将这个功能 ...
- ExtJS学习之MessageBox
MessageBox为ExtJS中的消息对话框,包括alert confirm prompt show四种. 1.index.html <!DOCTYPE html PUBLIC " ...
- 【机器学习】激活函数(ReLU, Swish, Maxout)
https://blog.csdn.net/ChenVast/article/details/81382939 神经网络中使用激活函数来加入非线性因素,提高模型的表达能力. ReLU(Rectifie ...
- “由于无法验证发行者,所以WINDOWS已经阻止此软件”的解决方法
Vista 和 Windows7 系统都很注重系统的安全性,在提高安全性的同时,也给我们某些应用带来不便,例如需要安装插件或证书,可能会弹出“由于无法验证发行者,所以WINDOWS已经阻止此软件”的相 ...
- Android EditText自定义样式
第一步:为了更好的比较,准备两个一模一样的EditText(当Activity启动时,焦点会在第一个EditText上,如果你不希望这样只需要写一个高度和宽带为0的EditText即可避免,这里就不这 ...
- Android基础之内容提供者的实现
内容提供者可以实现应用间查询数据库的需求 一.在提供数据库访问的应用设置内容提供者 public class AccountProvider extends ContentProvider { sta ...
- 进程管理-PV操作
1.临界资源:诸进程需要互斥方式对其进行共享的资源. 2.临界区:每个进程中访问临界资源的那段代码. 3.信号量:一种特殊的变量.
- [20171120]11g select for update skip locked.txt
[20171120]11g select for update skip locked.txt --//11G在select for update遇到阻塞时可以通过skipped locked跳过阻塞 ...
- [SQLSERVER] 转移数据库MDF或LDF文件位置的方法,以及重新启动出现无权限的问题
0. 查看数据库文件名和物理文件名 SELECT name, physical_name AS current_file_location FROM sys.master_files 1. 运行命令 ...
- C#微信公众号开发——获取access_token
access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token.正常情况下access_token有效期为7200秒(两个小时),微信获取access_token接 ...