2024.8.23

news2024/9/22 7:36:50

130124202408231008


DATE #:20240823

ITEM #:DOC

WEEK #:FRIDAY

DAIL #:捌月二十

TAGS
	
< BGM = "Forest Mixtape(Tsuki)" >
< theme = oi-graph theory Eulerian >
< [NULL] >
< [空] > 
< [空] >
冰岛的温柔是克莱因蓝再加点莫奈的灰。

BEST定理

BEST定理是用于处理欧拉回路计数问题的

我们首先做如下定义:

t x t_x tx为以x为根的树数量,可以使用矩阵树定理求解

d e g i deg_i degi为i的度

对于一个有向欧拉图,它的欧拉回路数量是:
t s d e g s ! ∏ i ∈ V ( d e g i − 1 ) ! [ i ≠ s ] = t x ∏ i ∈ V ( d e g i − 1 ) ! t_sdeg_s!\prod_{i\in V}(deg_i-1)![i\ne s]=t_x\prod_{i\in V}(deg_i-1)! tsdegs!iV(degi1)![i=s]=txiV(degi1)!

证明

我们发现,对于一个欧拉图而言,从每个点出发是一样的,所以考虑以1为起点

计算以1为根的生成树数量,将点i删去,在考虑生成树就是以该节点为根的生成树数量

生成树使用矩阵树定理求出


对于一棵树,我们这里激进一点,就让他是一棵根向树

对每一条边,我们给定一个顺序,指向根的顺序最靠后

那么顺序的方案数就是 d e g s ! ∏ ( d g e u − 1 ) ! [ u ≠ s ] deg_s!\prod(dge_u-1)![u\ne s] degs!(dgeu1)![u=s]

再乘上以1为根的生成树数量就是原式了

那么我们只要证明每种标号方案都对应这一种欧拉回路就可以了

在每次经过一条边后,我们删去它

剩下的边一定要满足如下条件才是欧拉图

  • 图弱联通

  • 只有两个节点出度和入度相差一,其他节点正常

(正常欧拉图所有节点入度等于出度

若删去的边 ( u , v ) (u,v) (u,v) 是非树边,由于树边是每个点最后离开的边 ( u , v ) (u,v) (u,v) 之间的树边一定还没有被删去,则 u u u v v v 之间可以直接通过树边形成弱连通;

若删去的边是树边,则删去后 u u u 与剩下的图完全断开,相当于删去了一条链末端的一条边,剩余边仍然弱连通。

所以删掉一条边后剩下的图仍然有欧拉路径.

每个边所在的顺序都是合法且不重复的欧拉路径

P5807 【模板】BEST 定理 | Which Dreamed It

【模板】BEST 定理 | Which Dreamed It

题目描述

n n n 个房间,每个房间有若干把钥匙能够打开特定房间的门。

最初你在房间 1 1 1。每当你到达一个房间,你可以选择该房间的一把钥匙,前往该钥匙对应的房间,并将该钥匙丢到垃圾桶中。

你希望最终回到房间 1 1 1,且垃圾桶中有所有的钥匙。

你需要求出方案数,答案对 1 0 6 + 3 10^6 + 3 106+3 取模。两组方案不同,当且仅当使用钥匙的顺序不同。

注意,每把钥匙都是不同的。

原 BZOJ3659。

输入格式

本题有多组数据。

第一行一个整数 T T T,表示数据组数。

对于每组数据:

第一行一个整数 n n n

接下来 n n n 行,第 i i i 行描述房间 i i i

首先一个数 s s s,表示这个房间的钥匙数目,接下来 s s s 个数,分别描述每把钥匙能够打开的房间的门。

输出格式

对于每组数据,一行一个整数,表示答案对 1 0 6 + 3 10^6+3 106+3 取模后的值。

样例 #1

样例输入 #1

2
1
0
2
1 1
1 2

样例输出 #1

1
0

提示

【样例说明】

在第一组样例中,没有钥匙,则方案数为 1 1 1

在第二组样例中,你不可能使用第二个房间的钥匙,所以方案数为 0 0 0

【数据范围】

对于 50 % 50\% 50% 的数据, n ≤ 4 n \le 4 n4 ∑ s ≤ 30 \sum s \le 30 s30

对于 100 % 100\% 100% 的数据, 1 ≤ T ≤ 15 1 \le T \le 15 1T15 1 ≤ n ≤ 100 1 \le n \le 100 1n100 0 ≤ ∑ s ≤ 3141592 0 \le \sum s \le 3141592 0s3141592

2021/5/14 加强 by SSerxhs&滑大稽

//2024.8.23
//by white_ice
//【模板】BESt 定理 | Which kdreamed kit | mod5807
//model
#include<bits/stdc++.h> 
//#include"need.cpp"
using namespace std;
#define itn long long 
#define int long long
constexpr int oo = 110;
constexpr int op = 500010;
constexpr int mod = 1000003;
int t;int n;
int ki[op];int fa[op];
itn res;itn fac[op];itn deg[op];
itn kd[oo][oo];itn kk[oo][oo];itn ka[oo][oo];
__inline itn Gauss(){
    itn ans = 1;
    for (int i=1;i<n;i++){
        for (int j=i+1;j<n;j++){
            while(kk[j][i]){
                itn t = kk[i][i]/kk[j][i];
                for(int k=i;k<n;k++)
                    kk[i][k] = (kk[i][k]-t*kk[j][k])%mod;
                swap(kk[i], kk[j]),ans=(-ans%mod+mod)%mod;
            }
        }
		if (kk[i][i]) (ans *= kk[i][i])%=mod;
    }
    return (ans % mod + mod) % mod;
}
__inline void clear(){
    memset(kk,0,sizeof(kk));
    memset(ka,0,sizeof(ka));
    memset(kd,0,sizeof(kd));
    memset(ki,0,sizeof(ki));
	for (int i=1;i<=n;i++)fa[i] = i;
}
__inline int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
main(void){
    //fre();
    cin.tie(0)->sync_with_stdio(0);
    cin >> t;fac[0] = 1;
    for (itn i=1;i<=500000;i++)
        fac[i] = fac[i-1]*i%mod;
    while (t --){
        cin >> n;clear();
        for (int i=1;i<=n;i++){
            int k, s;cin >> s;deg[i] = s;
            for (int j=1;j<=s;j++){
                cin >> k;ka[i][k]++,kd[k][k]++,ki[k]++;
                if (find(i) != find(k))
                    fa[find(i)]=find(k);
            }
        }
        for (int i=1;i<=n;i++)
            for (int j=1;j<=n;++j)
                kk[i][j] = ((kd[i][j]-ka[i][j])%mod+mod)%mod;
        for (int i=1;i<=n;i++)
            if (ki[i] != deg[i])  goto x1;
        for (int i=1;i<=n;i++)
            if (find(i)!=find(1)&&deg[i]) goto x1;
        res = deg[1]*Gauss()%mod;
        for (int i = 1;i <= n;i++)
            if (deg[i]) (res *= fac[deg[i]-1])%=mod;
        for (int i = 2;i <= n;i++) 
            if (find(i) == find(1)) goto x2;
        cout << fac[deg[1]] << '\n';continue;
        x1: puts("0");continue;
        x2: cout << res << '\n';
    }
    exit(0);
}

[AGC051D] C4

[AGC051D] C4

题面翻译

有一张 4 4 4 个点 4 4 4 条边的简单无向连通图,点的编号分别为 1 , 2 , 3 , 4 1,2,3,4 1,2,3,4 ,边分别连接着 $e1:(1,2),e2:(2,3),e3:(3,4),e4:(4,1) $。

给定 4 4 4 个数 v 1 , v 2 , v 3 , v 4 v_1,v_2,v_3,v_4 v1,v2,v3,v4 求满足以下条件的路径数量:

1 1 1 号点出发并到 1 1 1 号点结束,且经过第 i i i 条边 e i e_i ei 恰好 v i v_i vi 次。

你需要输出路径数对 998244353 998244353 998244353 取模的结果。

v 1 , v 2 , v 3 , v 4 ≤ 5 × 1 0 5 v_1,v_2,v_3,v_4 \le 5 \times 10^5 v1,v2,v3,v45×105

题目描述

以下の無向グラフにおいて、$ S $ から $ S $ へのウォークであって辺 $ ST $, $ TU $, $ UV $, $ VS $ をそれぞれ $ a $, $ b $, $ c $, $ d $ 回通るもの (向きは不問) の数を $ 998,244,353 $ で割った余りを求めてください。

输入格式

入力は標準入力から以下の形式で与えられる。

$ a $ $ b $ $ c $ $ d $

输出格式

答えを出力せよ。

样例 #1

样例输入 #1

2 2 2 2

样例输出 #1

10

样例 #2

样例输入 #2

1 2 3 4

样例输出 #2

0

样例 #3

样例输入 #3

470000 480000 490000 500000

样例输出 #3

712808431

提示

注記

$ S $ から $ S $ へのウォークとは、頂点の列 $ v_0\ =\ S,\ v_1,\ \ldots,\ v_k\ =\ S $ であって、各 $ i\ (0\ \leq\ i\ <\ k) $ について $ v_i $ と $ v_{i+1} $ を結ぶ辺があるものをいいます。 $ 2 $ つのウォークは、列として異なるときに異なるとみなされます。

制約

  • $ 1\ \leq\ a,\ b,\ c,\ d\ \leq\ 500,000 $
  • 入力中の全ての値は整数である。

Sample Explanation 1

条件を満たすウォークは $ 10 $ 個あり、その一例は $ S $ $ \rightarrow $ $ T $ $ \rightarrow $ $ U $ $ \rightarrow $ $ V $ $ \rightarrow $ $ U $ $ \rightarrow $ $ T $ $ \rightarrow $ $ S $ $ \rightarrow $ $ V $ $ \rightarrow $ $ S $ です。

//2024.8.23
//by white_ice
//[AGC051D] C4 | AT_agc051_d
//BEST定理
#include<bits/stdc++.h>
//#include"need.cpp"
using namespace std;
#define itn long long 
#define int long long 
constexpr int mod = 998244353;
constexpr int oo = 1000006;
int fac[oo],ifac[oo];itn a,b,c,d;
void init(){
	fac[0]=fac[1]=ifac[1]=ifac[0]=1;
	for(int i=2;i<=600000;++i)ifac[i]=(mod-mod/i)*ifac[mod%i]%mod;
	for(int i=2;i<=600000;++i)fac[i]=fac[i-1]*i%mod,ifac[i]=ifac[i]*ifac[i-1]%mod;
}
int check(){
	if((a&1)!=(b&1))return 1;
	if((b&1)!=(c&1))return 1;
	if((c&1)!=(d&1))return 1;
	return 0;
}
int check2(int i,int j,int k){
	if(i<0||i>b)return 1;
	if(j<0||j>c)return 1;
	if(k<0||k>d)return 1;
	return 0;
}
__inline int get(int st,int tu,int uv,int vs){int sv=d-vs,ut=b-tu,vu=c-uv;
return (st*tu*uv%mod+sv*st*tu%mod+sv*vu*ut%mod+sv*vu*st%mod)%mod;}
main(void){
    //fre();
    cin.tie(0)->sync_with_stdio(0);
    cin >> a >> b >> c >> d;
	init();
	if(check()){cout<<0;return 0;}
	int out=0;
	for(int xa=0;xa<=a;++xa){
		int xb=xa+(b-a)/2,xc=xb+(c-b)/2,xd=xc+(d-c)/2;
		if(check2(xb,xc,xd))continue;
		int tmps=d+xa-xd;itn tmpt=a+xb-xa;
        itn tmpu=b+xc-xb;itn tmpv=c+xd-xc;
		int tmp=(fac[tmps-1]*fac[tmpt-1]%mod)*(fac[tmpu-1]*fac[tmpv-1]%mod)%mod;
		int itmp1=(ifac[xa]*ifac[a-xa]%mod)*(ifac[xb]*ifac[b-xb]%mod)%mod;
		int itmp2=(ifac[xc]*ifac[c-xc]%mod)*(ifac[xd]*ifac[d-xd]%mod)%mod;
		int itmp=itmp1*itmp2%mod;
		out=(out+get(xa,xb,xc,xd)*tmps%mod*tmp%mod*itmp%mod)%mod;
	}
	cout << out << flush;
    exit (0);
}

首先想到可以拆边,将一条边,拆成很多条,

题目就可以转化,即:求从S出发的欧拉路数

显然应当使用BEST定理求解,但是BEST有局限性:要求图有向

所以我们要将无向图转化为有向图处理

对于任意一组边,比如 S ⟷ T S \longleftrightarrow T ST,共有a条,

我们考虑将其拆成 x a x_a xa S → T S \rightarrow T ST a − x a a-x_a axa T → S T\rightarrow S TS的边

因为是欧拉回路的缘故,所以我们的拆分并不那么自由要有一定的限制

欧拉回路中,每个节点出度等于入度

所以。。。。
x a + b − x b = a − x a + x b ⇒ x b = x a + b − a 2 x_a+b-x_b = a-x_a+x_b \Rightarrow\\ x_b = x_a+\frac{b-a}{2} xa+bxb=axa+xbxb=xa+2ba
同理,另外的 x c , x d x_c,x_d xc,xd也可以这么推出

所以欧拉图数量 e c ( V ) ec(V) ec(V)就可以求出来了

但是对于这道题,还要加上一些东西:

  1. 题目中要求了起点,所以要乘上S的出度 d e g s deg_s degs
  2. BEST定理中每条边都不同,但是在此题中,重边相同,所以答案要除以 ∏ e ∈ { a , b , c , d } x e ! ( e − x e ) ! \prod_{e\in \{a,b,c,d\}}x_e!(e-x_e)! e{a,b,c,d}xe!(exe)!

答案就是:
e c ( V ) × d e g s ∏ e ∈ { a , b , c , d } x e ! ( e − x e ) ! \frac{ec(V)\times deg_s}{\prod_{e\in \{a,b,c,d\}}x_e!(e-x_e)!} e{a,b,c,d}xe!(exe)!ec(V)×degs

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2068883.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用nfs搭建文件共享系统,以及windows环境如何访问linux系统中的文件共享目录

31、简介 在一些场景中&#xff0c;我们需要多台机器进行磁盘文件共享&#xff0c;集群中如果有linux机器&#xff0c;也有windows机器&#xff0c;如何设置进行文件共享&#xff0c;本文将详细说明。 注&#xff1a;本文linux系统使用的是 centos7&#xff0c;windows使用的是…

【Qt】常见控件 —— QWidget

文章目录 QWidget 的基本介绍QWidget 的 enable 属性QWidget 的 geometry属性 QWidget 的基本介绍 Qt 中 的 各种控件 都继承自 QWidget类 在 Qt designer 右侧 就显示出 QWidget的各种属性 并且也可以直接进行编辑 QWidget 的 enable 属性 enable 描述一个控件是否处于可用 …

前端面试题整理-webpack

实现前端模块化&#xff0c;将多个 js&#xff0c;打包成一个 bundle.js (其他类型文件交由各自的 loader 处理) 1. webpack 了解吗&#xff1f;大概介绍一下 一种打包工具&#xff0c;实现前端模块化&#xff0c;将多个 js&#xff0c;打包成一个 bundle.js (其他类型文件交…

Linux中查看端口被哪个进程占用、进程调用的配置文件、目录,address already in use端口被占用杀死并释放端口

1.查看被占用的端口的进程&#xff08;netstat和ss是一样的&#xff0c;较新的系统推荐ss&#xff09;: netstat -antulp | grep 端口号ss -antulp | grep :端口号lsof -i | grep 端口号2. 通过上面的命令就可以列出&#xff0c;这个端口被哪些应用程序所占用&#xff0c;然后找…

Java设计模式之策略模式详细讲解和案例示范

Java设计模式之策略模式详细讲解和案例示范 在软件开发中&#xff0c;策略模式是一种常见且非常有用的设计模式。它允许定义一系列算法&#xff0c;将它们一个个封装起来&#xff0c;并且使它们可以互相替换。策略模式让算法可以独立于使用它们的客户端而变化。本篇文章将详细…

VScode的python虚拟环境

1 创建虚拟环境&#xff08;venv&#xff09; 在VSCode中打开项目文件夹&#xff0c;键盘按住快捷键ctrl shift p&#xff0c;打开命令面板&#xff0c;输入python:创建环境 选择venv&#xff0c;输入解释器路径&#xff0c;此时左侧文件夹内会出现一个.venv文件夹 2 激活虚拟…

未来已来:探索机器学习如何重塑人工智能的未来方向

引言&#xff1a;机器学习室实现人工智能的关键技术手段&#xff0c;应用领域持续延伸 机器学习是人工智能的一个重要分支&#xff0c;主要研究如何让计算机系统通过数据学习并做出决策或预测&#xff0c;而不需要明确的编程。简单来说&#xff0c;就是让计算机利用经验来提高性…

C# 如何实现接口事件:详解与示例

文章目录 实现接口事件的步骤示例&#xff1a;实现接口事件1. 定义接口事件2. 实现接口事件3. 订阅和触发事件4. 使用示例 总结 在C#中&#xff0c;接口&#xff08;interface&#xff09;是一种定义类必须实现的方法和属性的抽象类型。除了方法和属性&#xff0c;接口还可以包…

浅谈红队攻防之道-CobaltStrike钓鱼攻击集锦

打个比方&#xff0c;一片大地上&#xff0c;躺着一群沉睡的人&#xff0c;远处就是火山&#xff0c;马上就要爆发了&#xff0c;你就像个闹钟&#xff0c;面对这些沉睡的人&#xff0c;你想把他们叫醒。 你持续不断地响着&#xff0c;有的睡得浅的人&#xff0c;被你叫醒了&am…

区块链基础通识(1)——分布式系统的共识问题

分布式系统 我们最初了解区块链的时候&#xff0c;很多人会形容这个区块链是一个“分布式的不可篡改账本”&#xff0c;这是一个很形象的说法&#xff0c;但是我认为更为准确的形容是“所有节点共同维护的状态机”。为什么分布式和区块链不能划等号呢&#xff1f; 两种常见的…

Ubuntu 22.04中解决Could not load the Qt platform plugin “xcb“问题解决方法

摘要&#xff1a;在Ubuntu 22.04中安装OpenCV后&#xff0c;遇到“load the Qt platform plugin “xcb” in site-packages/cv2/qt/plugins" even though it was found. 的问题&#xff0c;导致程序无法启动。本文详细探讨了该问题的成因&#xff0c;并介绍了几种常见但无…

在线英语学习小程序App源码开发技术探讨

引言 随着信息技术的飞速发展和全球化进程的加快&#xff0c;英语学习已经成为越来越多人的日常需求。传统的纸质材料和课堂教学已经无法满足现代人灵活、高效的学习需求。因此&#xff0c;开发一款在线英语学习小程序App成为了一个热门话题。本文将从技术角度探讨在线英语学习…

SX_gitlab图形化案例_19

由图形去理解gitlab反而更直观&#xff1a; 圆圈代表着本机代码所在的位置 这就代表着&#xff0c;本机的代码和远程仓库&#xff0c;jhy_gnss的代码是一样的 一个原点代表着一次改动 merge branch ‘jhy_gnss’ of 192.168.91.10:t3000 into jhy_gnss 这条命令是将GitLab服…

Frog4Shell — FritzFrog 僵尸网络将一日攻击纳入其武器库

FritzFrog 的背景 Akamai 通过我们的全球传感器网络持续监控威胁,包括我们之前发现的威胁。其中包括FritzFrog 僵尸网络(最初于 2020 年发现),这是一个基于 Golang 的复杂点对点僵尸网络,经过编译可同时支持基于 AMD 和 ARM 的机器。该恶意软件得到积极维护,多年来通过增…

基于FPGA的ASIC prototype验证

在当今快速发展的电子设计自动化&#xff08;EDA&#xff09;领域&#xff0c;专用集成电路&#xff08;ASIC&#xff09;的开发因其高性能、低功耗和定制化的特点而备受青睐。然而&#xff0c;ASIC的设计和制造过程不仅成本高昂&#xff0c;而且周期漫长&#xff0c;一旦进入生…

数学建模之数据分析【八】:数据预处理之数据格式化

文章目录 一、在Pandas中格式化数据框的浮点列1.1 将列值四舍五入到两位小数1.2 使用逗号和小数精度的 Pandas DataFrame 格式1.3 在 Pandas DataFrame 中格式化和缩放人口数据 二、如何检查Pandas DataFrame 中的数据类型2.1 创建 DataFrame 检查 DataType2.1.1 创建数据集2.1…

《前端攻城狮 · Vue 使用腾讯地图》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

React18快速入门教程

项目流程 开发流程 技术选型 创建项目 执行命令&#xff1a; pnpm create vite项目配置 editorconfig&#xff1a;用于配置编辑器&#xff0c;实现使用不同的编辑器打开效果是相同的包配置&#xff1a;主要用于配置国内源eslint配置&#xff1a;主要用于配置语法规则prettier&…

leetCode - - - 二分查找

目录 1.二分查找&#xff08;Leetcode 704&#xff09; 2.搜索插入位置&#xff08; LeetCode 35 &#xff09; 3.寻找峰值&#xff08;LeetCode 162&#xff09; 4.旋转数组的最小数字&#xff08;BM21&#xff09; 5.总结 1.二分查找&#xff08;Leetcode 704&#xff0…

基于Python的机器学习系列(7):多元逻辑回归

在本篇博文中&#xff0c;我们将探讨多元逻辑回归&#xff0c;它是一种扩展的逻辑回归方法&#xff0c;适用于分类数量超过两个的场景。与二元逻辑回归不同&#xff0c;多元逻辑回归使用Softmax函数将多个类别的概率输出映射到[0, 1]范围内&#xff0c;并确保所有类别的概率和为…