前言

\(2024.11.21\) 联考第三题,本人由于太菜没有推出 \(m=p^x\) 的性质遂部分分跑路,作文以记之。

简要题意

对于一个长度为 \(n\),值域为 \([0,m-1]\) 的序列 \(A\),若 \(A\) 满足 \(\Pi_{x\in A}x\equiv res\pmod m\) 则称 \(A\) 是好的。求好序列的方案数。

数据范围:\(1\le n\le10^9,1\le res\le m\le10^{12}\)。

题解

因为联考时给了一些部分分,里面有一定的提示,所以难度小了很多。此题解大体按照部分分性质讲解。

基本情况

首先我们讨论 \(m=p,p\in prime\) 的情况。

如果这个时候 \(res=0\),说明序列的乘积是 \(m\) 的倍数。但是 \(m\) 已经是一个质数,且序列中的数全部小于 \(m\)。这时只有当序列中有 \(0\) 存在时才对答案有贡献。稍加容斥,答案就是 \(m^n-(m-1)^n\)。

如果 \(res\) 不为零,肯定不能选 \(0\)。我们其实可以先随便选择前 \(n-1\) 个数,然后这前 \(n-1\) 个数就可以确定最后一个数。证明一下:首先前 \(n-1\) 个数的乘积取模后肯定在 \([0,m-1]\),令这个乘积为 \(x\),然后因为 \(m\) 是质数,所以 \(x\) 的 \([0.m-1]\) 倍在模 \(m\) 的意义下一定对应 \([0,m-1]\),且是一一对应的关系,所以可以唯一确定 \(A_n\)。所以这种情况方案数为 \((m-1)^{n-1}\).

现在扩展一下,若 \(m=p^x,p\in prime\) 时我们又该如何计算方案?我们还是得分两种情况讨论。

拓展1

如果 \(res=0\),说明序列的乘积得是 \(m\) 的倍数,换句话说也就是 \(p^x\) 的倍数。翻译一下,我们要让 \(A\) 中包含至少 \(x\) 个 \(p\),其他数在合法范围内随便选。然后因为 \(m\le10^{12}\),所以 \(x\le40\)。我们就可以容斥一下,转化成总方案数减去序列中少于 \(x\) 个 \(p\) 的方案数。所以我们现在需要求解这样一个问题:

若我们钦定序列中有 \(i\) 个 \(p\),序列方案数。

问题转化

我们换一个视角,也就是把 \(i\) 个 \(p\) 放入 \(n\) 个位置的方案数且同一位置可放多个也可以不放。这不就是把 \(i\) 个相同的球放入 \(n\) 个不同的盒子且盒子可为空吗?这就是一个很经典的组合数问题了,而且证明不重要故直接给出结论。方案数是 \(n+i-1\choose n-1\),然后换一下变成 \(n+i-1\choose i\),于是就可以线性预处理了。

考虑完 \(p\) 的放置情况后我们还要考虑正常填数的方案。接下来的部分也就是笔者赛时没有想通的地方。对于一个位置 \(i\),如果我已经放了一个 \(p^{c_i}\),是否就意味着这里不能继续填数了呢?答案是否定的。其实我只要选出一个数 \(t\) 满足 \(t\times p^{c_i}<m\) 就行,所以我们对于每一位都要考虑。因为填了一些 \(p\) 之后对现在选数只有范围的限制

知道这个有什么关系吗?就是你不用考虑一个位置是否填数,而是考虑填数的范围。这显然满足乘法原理。现在考虑范围,对于位置 \(i\) 已经填了 \(p^{c_i}\),我还能乘上哪些数?首先排除 \(p\) 的倍数,因为我已经把 \(p\) 填好了。所以我们填的一个数一定是 \(y\times p+d,d\in[1,p)\) 的形式。然后我们填数还要满足小于 \(m\),所以有 \((y\times p+d)\times p^{c_i}<p^x\),把 \(p^{c_i}\) 移项可得 \(y\times p+d<p^{x-c_i}\)。

翻译成人话就是我们选的数小于 \(p^{x-c_i}\) 且不为 \(p\) 的倍数。也许你会有疑问,\(c_i\) 怎么处理?先别急,看到后面你就懂了。我们先关注 \(y\times p+d\) 中的 \(y\) 取值范围,这显然是 \([0,p^{x-c_i-1})\);然后 \(d\) 的范围前面提到过是 \([1,p)\),所以位置 \(i\) 可以选择的方案就是 \(p^{x-c_i-1}\times(p-1)\)。然后总方案就是把 \(n\) 个位置的方案乘起来:

\[\prod_{i=1}^n p^{x-c_i-1}\times(p-1)
\]

因为我钦定选了 \(i\) 个 \(p\),所以有 \(\sum c_j=i\)。当我们把上面的式子拆开时,就有:

\[p^{xn-\sum c_j-n}\times(p-1)^n
\]

然后你就发现所有 \(c_j\) 全部加在了一起变成一个 \(i\)。于是问题最终的答案就是:

\[{n+i-1\choose i}\times p^{xn-n-i}\times(p-1)^n
\]

解决了钦定有 \(i\) 个 \(p\) 时的方案,我们就可以用总方案减去所有小于 \(x\) 时的方案就可以得到 \(res=0\) 的答案:

\[p^{xn}-\sum_{i<x}{n+i-1\choose i}\times p^{xn-n-i}\times(p-1)^n
\]

拓展2

然后讨论 \(res\) 不为 \(0\) 的情况,这个时候我们最多都选不到 \(x\) 个 \(p\) 了。但是具体选多少还不好说。如果我把 \(res\) 拆一拆,写成 \(r\times p^y\) 的形式,你是否会有一些想法呢?

考虑我们现在要在序列中选出恰好 \(y\) 个 \(p\),这样把等式两边的 \(p^y\) 抵消后就变成了基本情况中的第二种。我们恰好选 \(y\) 个 \(p\) 的方案数是:

\[{n+y-1\choose y}\times p^{xn-n-y}\times(p-1)^n
\]

但是考虑到序列的乘积只满足了 \(p^y\) 的倍数,所以还要去重。考虑如何去重。思路是用现在求得的总方案数乘合法概率。考虑现在的序列会得出些什么结果,写成集合是 \(\{k\times p^y|\gcd(k,p)=1,k<p^{x-y}\}\)。然后类比之前求位置选数的方案数的方法可得 \(p^{x-y-1}\times(p-1)\)。考虑到如果我们已经确定了前 \(n-1\) 个数后,最后一个数就已经唯一确定(原因与之前类似)。 然后因为如果把等式两边同时除以 \(p^y\),两边的数都与 \(p^x\) 互质,所以在随机选数的情况下可以类比欧拉定理得出序列的乘积是均匀的。所以合法的概率就是 \(\frac{1}{p^{x-y-1}\times(p-1)}\),乘上总方案得到最终答案:

\[{n+y-1\choose y}\times p^{xn-x-n+1}\times(p-1)^{n-1}
\]

拓展3

现在讨论一般情况。基于以上的内容,我们考虑将 \(m\) 写成 \(p1^{c1}p2^{c2}p3^{c3}\dots p_k^{c_k}\) 的形式。我们可以先求出所有 \(\prod_{x\in A}x\equiv (res\bmod p_i^{c_i})\pmod {p_i^{c_i}}\) 的方案数然后再乘法原理直接乘。可是为什么直接做是对的呢?

证明

假设对于每一个子问题我们已经找出任意一组合法解,我们把这些等式写成下面形式:

\[(\prod x\bmod p_i^{c_i})\equiv (res\bmod p_i^{c_i})\pmod {p_i^{c_i}}
\]

令 \(T = \prod x\bmod p_i^{c_i}\),则我们现在就是在做中国剩余定理的合并。然后合并后的解一定合法,所以我们求出的任意一组解都可以合并,于是就直接乘起来即可。

代码

ll sol(ll rr, ll d, int x, ll mod){
if(! rr){
ll s = 0;
for(int i = 0; i < x; ++i)s = (s + C[i] * qmi(d, x * n - n - i) % p * qmi(d - 1, n)) % p;
return (qmi(mod, n) - s + p) % p;
}
int y = 0; while(rr % d == 0)rr /= d, ++y;
return C[y] * qmi(d, x * n - n - x + 1) % p * qmi(d - 1, n - 1) % p;
} ll ans = 1; signed main(){
freopen("equiv.in", "r", stdin);
freopen("equiv.out", "w", stdout);
n = rd(), r = rd(), m = rd(); C[0] = 1;
for(int i = 1; i < 50; ++i)C[i] = C[i - 1] * (n + i - 1) % p * qmi(i, p - 2) % p;
for(ll i = 2; i * i <= m; ++i)if(m % i == 0){
int c = 0; ll x = 1; while(m % i == 0) m /= i, x *= i, ++c;
ans = ans * sol(r % x, i, c, x) % p;
}
if(m > 1)ans = ans * sol(r % m, m, 1, m) % p;
wt(ans);
return 0;
}

ABC245Ex题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

  10. JSOI2016R3 瞎BB题解

    题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...

随机推荐

  1. 【C#】【报错解决】分析器错误消息: 未能找到 CodeDom 提供程序类型“Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider

    1.工具->NuGet包管理器->程序包管理控制台 2.在程序包管理控制台中输入 PM> Install-Package Microsoft.CodeDom.Providers.Do ...

  2. 由于OpenCV的#include <opencv2/opencv.hpp>文件没有放在所有的头文件之前所引起的编译时提示很多错误,如:filesystem.hpp(11,12): error C2144: 语法错误:“bool”的前面应有“;”error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int等

    现象描述: 由于OpenCV的#include <opencv2/opencv.hpp>文件没有放在所有的其他OpenCV头文件之前所引起的编译时提示很多错误,如:filesystem.h ...

  3. [转]Vue3.0和Vue2.0的区别

    Vue3.0和Vue2.0的区别默认进行懒观察(lazy observation).在 2.x 版本里,不管数据多大,都会在一开始就为其创建观察者.当数据很大时,这可能会在页面载入时造成明显的性能压力 ...

  4. [转]vue项目启动时,npm run serve 和 npm run dev 的区别

    npm run serve 和 npm run dev 的区别 在我们运行一些 vue 项目的时候,输入npm run serve或者 npm run dev的其中一个时,系统会报错: PS C:\U ...

  5. Intellij IDEA开发环境中Springboot项目无Run ****main()的菜单

    问题描述: Intellij  IDEA开发环境中Springboot项目无Run ****main()的菜单. 解决办法有以下几种: 方法1:Idea无右键run选项, 无法通过main方法启动sp ...

  6. Web网页端IM产品RainbowChat-Web的v7.1版已发布

    一.关于RainbowChat-Web RainbowChat-Web是一套Web网页端IM系统,是RainbowChat的姊妹系统(RainbowChat是一套基于开源IM聊天框架 MobileIM ...

  7. KMS for Windows 11

    I. 镜像下载 Windows 镜像下载地址:站点1,站点2 II. 手动激活 参考文档:Easy ways to activate Windows 11 for FREE without a pro ...

  8. manim边做边学--动画轨迹

    本篇介绍Manim中两个和动画轨迹相关的类,AnimatedBoundary和TracedPath. AnimatedBoundary聚焦于图形边界的动态呈现,能精准控制边界绘制的每一帧,助力我们清晰 ...

  9. WxPython跨平台开发框架之模块字段权限的管理

    在我的很多Winform开发项目中,统一采用了权限管理模块来进行各种权限的控制,包括常规的功能权限(工具栏.按钮.菜单权限),另外还可以进行字段级别的字段权限控制,字段权限是我们在一些对权限要求比较严 ...

  10. linux服务器下 conda 配置清华源

    安装miniconda 下载安装脚本 wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-latest-Li ...