摆(行列式、杜教筛)

有一个 n × n n\times n n×n 的矩阵 A A A,满足:
A i , j = { 1 i = j 0 i ≠ j ∧ i ∣ j C otherwise A_{i,j}=\begin{cases} 1 &i=j\\ 0 &i\not=j\land i\mid j\\ C &\text{otherwise} \end{cases} Ai,j= 10Ci=ji=jijotherwise

det ⁡ ( A ) \det(A) det(A)。答案模 998244353 998244353 998244353

n ≤ 1 0 11 n\le10^{11} n1011


显然当 C = 0 C=0 C=0 时答案为 1 1 1,当 C = 1 C=1 C=1 时若 n ≤ 2 n\le2 n2 则答案为 1 1 1 否则为 0 0 0

首先 A A A 形如:
[ 1 0 0 0 0 … C 1 C 0 C … C C 1 C C … C C C 1 C … C C C C 1 … ⋮ ⋮ ⋮ ⋮ ⋮ ⋱ ] \begin{bmatrix} 1&0&0&0&0&\dots\\ C&1&C&0&C&\dots\\ C&C&1&C&C&\dots\\ C&C&C&1&C&\dots\\ C&C&C&C&1&\dots\\ \vdots&\vdots&\vdots&\vdots&\vdots&\ddots \end{bmatrix} 1CCCC01CCC0C1CC00C1C0CCC1

考虑把主对角线的 1 1 1 换位 C + x C+x C+x,这样 det ⁡ ( A ) \det(A) det(A) 就可看做关于 x x x 的多项式,求值只需代入 x = 1 − C x=1-C x=1C 即可。

这里有个式子

det ⁡ ( A ) = ∑ S ⊂ { 1 , 2 , … , n } det ⁡ ( B S ) ⋅ x n − ∣ S ∣ \det(A)=\sum\limits_{S\subset\{1,2,\dots,n\}}\det(B_S)\cdot x^{n-|S|} det(A)=S{1,2,,n}det(BS)xnS

其中 B S B_S BS 表示把矩阵 A A A 主对角线元素换成 C C C,只选出行列都在 S S S 中的元素拼接形成的矩阵。

例如: B { 1 , 2 , 4 , 5 , 8 } = [ C 0 0 0 0 C C 0 C 0 C C C C 0 C C C C C C C C C C ] B_{\{1,2,4,5,8\}}=\begin{bmatrix} C&0&0&0&0\\ C&C&0&C&0\\ C&C&C&C&0\\ C&C&C&C&C\\ C&C&C&C&C\\ \end{bmatrix} B{1,2,4,5,8}= CCCCC0CCCC00CCC0CCCC000CC

证明考虑感性理解。设 i = n − ∣ S ∣ i=n-|S| i=nS,对于 x i x^{i} xi 的系数,考虑行列式的定义,要选出行列都互不相同的 n n n 个数相乘,由于只有主对角线上的 C + x C+x C+x 有次数贡献,于是考虑选出来 m m m 个主对角线上的元素( m ≥ i m\ge i mi),剩下的行列拼接在一起后面选。我们此时发现 n − m + m − i = n − i n-m+m-i=n-i nm+mi=ni,说明 B S B_S BS 是由 S S S 的行列与 m m m 行列之中选 m − i m-i mi 个组成的, ( C + x ) m (C+x)^m (C+x)m x i x^i xi 的系数为 ( m i ) C m − i \binom{m}{i}C^{m-i} (im)Cmi,恰好满足条件。

我们观察 B S B_S BS,发现如果 S S S 中元素两两整除,那么 B S B_S BS 是下三角矩阵, det ⁡ ( B S ) = C ∣ S ∣ \det(B_S)=C^{|S|} det(BS)=CS。否则可以证明 det ⁡ ( B S ) = 0 \det(B_S)=0 det(BS)=0

考虑归纳法证明,如果 S S S 中存在两个数不为 S S S 中其他任何数的因子,那么矩阵中就会出现两行 C C C det ⁡ ( B S ) = 0 \det(B_S)=0 det(BS)=0;否则 S S S 中最大的数一定是其他数的倍数,从而只有最后一行全为 C C C,不妨删去最后一行列。这样递归下去,容易发现结论成立。

r = C 1 − C r=\frac{C}{1-C} r=1CC,于是 det ⁡ ( A ) = ( 1 − C ) n ∑ S 中元素两两整除 r ∣ S ∣ \det(A)=(1-C)^n\sum\limits_{S中元素两两整除} r^{|S|} det(A)=(1C)nS中元素两两整除rS

f i f_i fi 表示所有满足 S S S 中最大元素为 i i i r ∣ S ∣ r^{|S|} rS 之和(特别地, f 1 = 1 + r f_1=1+r f1=1+r)。容易得到转移式子
f i = r ∑ j ∣ i , j < i f j f_i=r\sum\limits_{j\mid i,j<i}f_j fi=rji,j<ifj

s ( i ) = ∑ j = 1 i f j s(i)=\sum\limits_{j=1}^if_j s(i)=j=1ifj,我们要求出 s ( n ) s(n) s(n)

考虑杜教筛,我们构造 g ( n ) = { − 1 n = 1 r n > 1 g(n)=\begin{cases}-1&n=1\\r&n>1\end{cases} g(n)={1rn=1n>1,函数 h = f ∗ g h=f*g h=fg,容易验证 h ( n ) = { − r − 1 n = 1 0 n > 1 h(n)=\begin{cases}-r-1&n=1\\0&n>1\end{cases} h(n)={r10n=1n>1。套用公式 g ( 1 ) s ( n ) = ∑ i = 1 n h i − ∑ i = 2 n g ( i ) s ( ⌊ n i ⌋ ) g(1)s(n)=\sum\limits_{i=1}^nh_i-\sum\limits_{i=2}^ng(i)s(\lfloor\frac ni\rfloor) g(1)s(n)=i=1nhii=2ng(i)s(⌊in⌋),可以得到 s ( n ) s(n) s(n) 的转移式子
s ( n ) = 1 + r + r ∑ i = 2 n s ( ⌊ n i ⌋ ) s(n)=1+r+r\sum\limits_{i=2}^ns(\lfloor\frac ni\rfloor) s(n)=1+r+ri=2ns(⌊in⌋)

到此直接按式子求答案是 O ( n 3 4 ) O(n^{\frac34}) O(n43) 的,如果预处理出前 n 2 3 n^{\frac23} n32 s ( n ) s(n) s(n),求值可以做到 O ( n 2 3 ) O(n^{\frac23}) O(n32)

但是预处理时间复杂度容易带上 log ⁡ \log log,所以要考虑优化。

n = ∏ p i k i n=\prod p_i^{k_i} n=piki,如果我们把 p 1 , p 2 , … p_1,p_2,\dots p1,p2, 依次换成 2 , 3 , 5 , 7 , … 2,3,5,7,\dots 2,3,5,7,,所得到的数设为 n ′ n' n,容易发现 f n = f n ′ f_n=f_{n'} fn=fn。这启发我们 f n f_n fn 的值只与可重集 k k k 有关。通过暴力发现可重集的数量很少,于是我们可以暴力求出这些“代表”的函数值,然后让找到其他数所对应的“代表”。用欧拉筛实现,具体实现可参照代码。

总的时间复杂度为 O ( n 2 3 ) O(n^{\frac23}) O(n32)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=998244353,N=2e7+1;
ll n,c,R;
int a[N],p[N],cnt,m,to[N],num[N],Max[N];
ll S[N];
unordered_map<ll,int> ma;
ll ksm(ll a,ll b)
{ll ans=1;while(b){if(b&1) ans=ans*a%mod;b>>=1;a=a*a%mod;}return ans;
}
ll s(ll n)
{if(n<=m) return S[n];if(ma.count(n)) return ma[n];ll ans=1+R;for(ll i=2,r;i<=n;i=r+1){r=n/(n/i);ans=(ans+(r-i+1)%mod*R%mod*s(n/i))%mod;}return ma[n]=ans;
}
void init(int n)
{a[1]=1,to[1]=S[1]=1+R;for(int i=2;i<=n;i++){if(!a[i]){p[++cnt]=i;to[i]=2;num[i]=1;Max[i]=i;}if(to[i]==i){for(int j=1;j*j<=i;j++) if(i%j==0) S[i]=(S[i]+S[j]+(j*j<i&&j>1)*S[i/j])%mod;S[i]=S[i]*R%mod;}else S[i]=S[to[i]];for(int j=1;j<=cnt&&i*p[j]<=n;j++){int x=i*p[j];a[x]=1;Max[x]=Max[i];if(i%p[j]==0){num[x]=num[i];to[x]=to[x/Max[x]]*p[num[x]];break;}num[x]=num[i]+1;to[x]=to[x/Max[x]]*p[num[x]];}}for(int i=2;i<=n;i++) S[i]=(S[i]+S[i-1])%mod;
}
int main()
{freopen("bigben.in","r",stdin);freopen("bigben.out","w",stdout);cin>>n>>c;if(!c) cout<<1,exit(0);if(c==1) cout<<(n<=2),exit(0);R=c*ksm(1-c+mod,mod-2)%mod;init(m=min(n,N-1));cout<<s(n)*ksm(1-c+mod,n)%mod;
}

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

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

相关文章

FPGA时钟资源与设计方法——时钟抖动(jitter)、时钟偏斜(skew)概念讲解

目录 1时钟抖动&#xff08; clock jitter&#xff09;2 时钟偏斜&#xff08;clock skew&#xff09; 1时钟抖动&#xff08; clock jitter&#xff09; 时钟抖动&#xff08;Jitter&#xff09;&#xff1a;时钟抖动指的是时钟周期的不稳定性&#xff0c;即&#xff1a;时钟…

Milvus向量库安装部署

GitHub - milvus-io/milvus-sdk-java: Java SDK for Milvus. 1、安装Standstone 版本 参考&#xff1a;Linux之milvus向量数据库安装_milvus安装-CSDN博客 参考&#xff1a;Install Milvus Standalone with Docker Milvus documentation 一、安装步骤 1、安装docker docke…

使用八爪鱼爬取京东商品详情页数据

文章目录 一、前述1.1、采集场景1.2、采集字段1.3、采集结果1.4、采集工具 二、采集步骤2.1、登录网站2.1.1、登录入口2.1.2、京东账号登录2.1.3、登录完成 2.2、自动识别2.3、选取爬取的内容2.4、处理数据2.4.1、纵向字段布局2.4.2、更多字段操作2.4.3、格式化数据2.4.4、添加…

OpenAI最新模型Sora到底有多强?眼见为实的真实世界即将成为过去!

文章目录 1. 写在前面2. 什么是Sora&#xff1f;3. Sora的技术原理 【作者主页】&#xff1a;吴秋霖 【作者介绍】&#xff1a;Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作&#xff01; 【作者推荐】&#xff1a;对JS逆向感…

@ 代码随想录算法训练营第7周(C语言)|Day42(动态规划)

代码随想录算法训练营第7周&#xff08;C语言&#xff09;|Day42&#xff08;动态规划&#xff09; Day42、动态规划&#xff08;包含题目 416. 分割等和子集 &#xff09; 416. 分割等和子集 题目描述 给定一个只包含正整数的非空数组。是否可以将这个数组分割成两个子集&…

导出Excel,支持最佳

列表信息导出为Excel文件&#xff0c; 依赖pom&#xff1a; Sheet, Row:<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId> </dependency>XSSFWorkbook <dependency><groupId>org.apache.poi</…

Rust-所有权(ownership)

文章目录 前言一、管理计算机内存的方式所有权规则 二、Rust中的 moveCopy trait 三、Rust中的 clone总结 前言 Rust入门学习系列-Rust 的核心功能&#xff08;之一&#xff09;是 所有权&#xff08;ownership&#xff09;。引入这个概念是为了更好的管理计算机的内存。下面篇…

【0260】pg_filenode.map文件分析(内含map文件读取、解析demo)

1. 关于pg内核map file map文件是关键数据:我们没有从丢失或损坏中恢复的自动方法。我们使用CRC来检测损坏。为了最小化更新失败的风险, map文件应该保持在不超过一个标准大小的磁盘扇区(即512字节(bytes)),并且我们使用就地覆盖而不是玩重命名游戏。 下面的结构布局被设…

【动态规划】【组合数学】1866. 恰有 K 根木棍可以看到的排列数目

作者推荐 【深度优先搜索】【树】【有向图】【推荐】685. 冗余连接 II 本文涉及知识点 动态规划汇总 LeetCode1866. 恰有 K 根木棍可以看到的排列数目 有 n 根长度互不相同的木棍&#xff0c;长度为从 1 到 n 的整数。请你将这些木棍排成一排&#xff0c;并满足从左侧 可以…

Yii2项目使用composer异常记录

问题描述 在yii2项目中&#xff0c;使用require命令安装依赖时&#xff0c;出现如下错误提示 该提示意思是&#xff1a;composer运行时&#xff0c;执行了yiisoft/yii2-composer目录下的插件&#xff0c;但是该插件使用的API版本是1.0&#xff0c;但是当前的cmposer版本提供的…

Rust语言之sha-256爆破

文章目录 一、实现Sha-256加密1.创建项目2.编写Cargo.toml文件3.编写程序代码 二、sha256爆破1.获取命令行参数2.读取文件3.校验输入参数4.暴力破解 一、实现Sha-256加密 SHA-256是一种安全哈希算法&#xff0c;主要特点是将输入的数据&#xff08;无论长度&#xff09;通过特定…

Jmeter的自动化测试实施方案(超详细)

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号&#xff1a;互联网杂货铺&#xff0c;回复1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 Jmeter是目前最流行的一种测试工具&#xff0c;基于此工…

如何在 Angular 中使用懒加载路由

简介 延迟加载 是一种限制加载用户当前需要的模块的方法。这可以提高应用程序的性能并减小初始捆绑包大小。 默认情况下&#xff0c;Angular 使用 急切加载 来加载模块。这意味着在应用程序运行之前必须加载所有模块。虽然这对许多用例可能是足够的&#xff0c;但在某些情况下…

Pdoc:生成优雅Python API文档的工具

Pdoc&#xff1a;生成优雅Python API文档的工具 在开发Python项目时&#xff0c;文档是至关重要的。它不仅提供了对代码功能和用法的了解&#xff0c;还为其他开发人员提供了参考和使用的便利。Pdoc是一个流行的文档生成工具&#xff0c;专为生成Python API文档而设计。本文将介…

【NextJS】整个项目跨域配置

项目跨域是指&#xff1a;本项目作为被访问方&#xff0c;由另一个项目对本项目发起fetch等动作获取数据页面数据 实验环境&#xff1a; next: 14.1.0react: ^18 配置文件&#xff1a;next.config.[mjs|js|ts] 假定原始范本内容&#xff1a; /** type {import(next).NextCon…

STM32 USART入门指南

对于刚开始涉足STM32微控制器编程的初学者来说&#xff0c;掌握其通用同步/异步接收/发送器&#xff08;USART&#xff09;功能是一项基本且必要的技能。USART在嵌入式系统中广泛用于串行通信。本指南旨在简明扼要地介绍USART的基础概念和基本步骤&#xff0c;并提供一个简单的…

扯淡的DevOps,我们开发根本不想做运维!

引言 最初考虑引用“ DevOps 已死&#xff0c;平台工程才是未来”作为标题&#xff0c;但这样的表达可能太过于绝对。最终&#xff0c;决定用了“扯淡的”这个词来描述 DevOps&#xff0c;但这并不是一种文明的表达方式。 文章旨在重新审视 DevOps 和平台工程&#xff0c;将分别…

【c语言】人生重开模拟器

前言&#xff1a; 人生重开模拟器是前段时间非常火的一个小游戏&#xff0c;接下来我们将一起学习使用c语言写一个简易版的人生重开模拟器。 网页版游戏&#xff1a; 人生重开模拟器 (ytecn.com) 1.实现一个简化版的人生重开模拟器 &#xff08;1&#xff09; 游戏开始的时…

php捕获Fatal error错误与异常处理

在php5的版本中&#xff0c;如果出现致命错误是无法被 try {} catch 捕获的&#xff0c;如下所示&#xff1a; <?phperror_reporting(E_ALL); ini_set(display_errors, on);try {hello(); } catch (\Exception $e) {echo $e->getMessage(); } 运行脚本&#xff0c;最终…

GO语言的变量与常量

1.变量 go是一个静态语言 变量必须先定义后使用变量必须要有类型 定义变量的方式&#xff1a; var 名称 类型 var 名称 值 名称 :值 例如&#xff1a; var num int 这样就存了一个num类型为int的变量 var num 1 上面使用简化的定义通过num自动判断后面的类型为int并…