洛谷 P9007 [入門賽 #9] 最澄澈的空與海 (Hard Version)

這道題可不入門。

[Problem Discription] \color{blue}{\texttt{[Problem Discription]}} [Problem?Discription]

給定 n n n,求有多少組 ( x , y , z ) (x,y,z) (x,y,z) 滿足:

  1. x ? y z = n ! x-\dfrac{y}{z}=n! x?zy?=n!
  2. x ? y z = n ! n \dfrac{x-y}{z}=\dfrac{n!}{n} zx?y?=nn!?

其中 n ! n! n! 表示 n n n 的階乘,即 ∏ i = 1 n i \prod\limits_{i=1}^{n} i i=1n?i x , y , z x,y,z x,y,z 為整數,可以是負整數。

多組詢問。 1 ≤ T ≤ 1 × 1 0 5 , 1 ≤ n ≤ 1 × 1 0 6 1 \leq T \leq 1 \times 10^{5},1 \leq n \leq 1 \times 10^{6} 1T1×105,1n1×106

[Analysis] \color{blue}{\texttt{[Analysis]}} [Analysis]

作為一個經歷了高考摧殘的人,最會干的事情就是化簡冗長的式子。

干瞪眼看不出這兩個式子有什么規律,變量太多了,因此考慮先消元。

x ? y z = n ! x-\dfrac{y}{z}=n! x?zy?=n! x = y z + n ! x=\dfrac{y}{z}+n! x=zy?+n!,把它帶入第二個式子中可得:

x ? y z = y z + n ! ? y z = y + z n ! ? z y z 2 = n ! n \begin{aligned} \dfrac{x-y}{z}&=\dfrac{\dfrac{y}{z}+n!-y}{z}\\ &=\dfrac{y+zn!-zy}{z^2}\\ &=\dfrac{n!}{n} \end{aligned} zx?y??=zzy?+n!?y?=z2y+zn!?zy?=nn!??

通分,

n y ? n z n ! ? n z y = n ! z 2 n ( z ? 1 ) y = n ! z ( n ? z ) y = ( n ? 1 ) ! z ( n ? z ) z ? 1 \begin{aligned} ny-nzn!-nzy&=n!z^2\\ n(z-1)y&=n!z(n-z)\\ y&=\dfrac{(n-1)!z(n-z)}{z-1} \end{aligned} ny?nzn!?nzyn(z?1)yy?=n!z2=n!z(n?z)=z?1(n?1)!z(n?z)??

因此,滿足題意的 ( z ? 1 ) (z-1) (z?1) 一定是 ( n ? 1 ) ! z ( n ? z ) (n-1)!z(n-z) (n?1)!z(n?z) 的因數。除了 z = 2 z=2 z=2 外, ( z ? 1 ) (z-1) (z?1) 不會是 z z z 的因數,且 gcd ? ( z ? 1 , z ) = 1 \gcd(z-1,z)=1 gcd(z?1,z)=1,因此 ( z ? 1 ) (z-1) (z?1) ( n ? 1 ) ! ( n ? z ) (n-1)!(n-z) (n?1)!(n?z) 的因數。然而這個式子上下都含有 z z z,愚蠢的人腦是分析不出什么東西來的。

考慮引入新的參數 k k k

( n ? 1 ) ! ( n ? z ) = k ( z ? 1 ) n ! ? ( n ? 1 ) ! z = k z ? k [ ( n ? 1 ) ! + k ] z = n ! + k z = n ! + k ( n ? 1 ) ! + k \begin{aligned} (n-1)!(n-z)&=k(z-1)\\ n!-(n-1)!z&=kz-k\\ \left [ (n-1)!+k\right ]z&=n!+k\\ z&=\dfrac{n!+k}{(n-1)!+k} \end{aligned} (n?1)!(n?z)n!?(n?1)!z[(n?1)!+k]zz?=k(z?1)=kz?k=n!+k=(n?1)!+kn!+k??

實話實說,這是一個非常美的式子,可惜它和上面一樣,上下都含有 k k k,因此從難度上并沒有變化。

思路貌似到這里就斷了,怎么辦?當然是看題解去(bushi)。

上面是把消去了 x x x 保留 y y y,行不通的時候當然試試消去 y y y 留下 x x x 啦。

也不用重新計算,只需要把 y y y z z z 表達的那個式子帶入 x x x 中,就可以得到:

x = y z + n ! = ( n ? 1 ) ( n ? 1 ) ! z z ? 1 x=\dfrac{y}{z}+n!=\dfrac{(n-1)(n-1)!z}{z-1} x=zy?+n!=z?1(n?1)(n?1)!z?

同樣, z =? 2 z \not = 2 z=2 時, ( z ? 1 ) (z-1) (z?1) 不是 z z z 的因數,因此 ( z ? 1 ) (z-1) (z?1) 一定是 ( n ? 1 ) ( n ? 1 ) ! (n-1)(n-1)! (n?1)(n?1)! 的因數。 z = 2 z=2 z=2 時, z ? 1 = 1 z-1=1 z?1=1 當然也是 ( n ? 1 ) ( n ? 1 ) ! (n-1)(n-1)! (n?1)(n?1)! 的因數。

因此問題轉化為求 ( n ? 1 ) ( n ? 1 ) ! (n-1)(n-1)! (n?1)(n?1)! 的因數的個數。這個問題和原問題是等價的。記答案為 ans ( n ) \text{ans}(n) ans(n)

為什么?

考慮 ( n ? 1 ) ( n ? 1 ) ! (n-1)(n-1)! (n?1)(n?1)! 的一個因數 z z z,帶入上式就一定可以唯一的算出一個 x ( z ) , y ( z ) x(z),y(z) x(z),y(z) x ( z ) x(z) x(z) 必然是一個整數。而 y = z ( x ? n ! ) y=z(x-n!) y=z(x?n!)(由最開始的式子變形而來)在 x , z x,z x,z 都是整數的情況下當然是整數。因此一個 z z z 就唯一確定一組 ( x , y , z ) (x,y,z) (x,y,z),而不同的 z z z 確定的當然是不同的 ( x , y , z ) (x,y,z) (x,y,z)。兩個問題的解構成一一映射。

根據因數個數定理,我們需要求的就是 ( n ? 1 ) ( n ? 1 ) ! (n-1)(n-1)! (n?1)(n?1)! 不同質因數出現的次數。

設每個質因數出現的次數為 f ( p i ) f(p_{i}) f(pi?)。答案即為 ∏ i = 1 prime?count ( 1 + f ( p i ) ) \prod\limits_{i=1}^\text{prime count}\left (1+f(p_{i}) \right ) i=1prime?count?(1+f(pi?))

不能每次都重新求,考慮怎么從 ans ( n ? 1 ) \text{ans}(n-1) ans(n?1) 遞推得到 ans ( n ) \text{ans}(n) ans(n)

我們可以快速的將 n n n ( n ? 1 ) (n-1) (n?1) 分解質因數,然后 f ( p i ) f(p_{i}) f(pi?) 減去 ( n ? 1 ) (n-1) (n?1) 的質因數出現次數,加上兩倍的 n n n 的質因數個數就行了(因為階乘和階乘前各有一個 n n n,所以是兩倍)。

但是根號級別的分解質因數還是太慢了,能不能降低時間復雜度呢?

答案是可以的。如果我們知道 n n n 的質因數都有誰,就不用一個一個數去實驗了。當然不能把所有質因數都記下來(都記下來了還要試除法干嘛了),但是通過線性篩,我們可以順便得到每個數的最小質因數是多少。每次除以最小質因數就可以大大加快算法了。

配合線性求逆元,程序跑得飛快。

還漏了一個問題,在上面那個式子中, ( z ? 1 ) (z-1) (z?1) 是作為分母的,因此 z =? 1 z \not = 1 z=1。有沒有 z = 1 z=1 z=1 的情況呢?

z = 1 z=1 z=1 時有 x ? y = n ! = n ! n x-y=n!=\dfrac{n!}{n} x?y=n!=nn!?,因此 n = 1 n=1 n=1。因此只有 n = 1 n=1 n=1 時答案為無窮。

Code \color{blue}{\text{Code}} Code

int f[N],n,T,ans[N];int prime[N],prcnt;
bool is_prime[N];
int minn_prime[N];
void get_prime(int n){for(int i=2;i<=n;i++)is_prime[i]=true;for(int i=2;i<=n;i++){if (is_prime[i]){minn_prime[i]=i;prime[++prcnt]=i;}for(int j=1;j<=prcnt;j++){if (1ll*i*prime[j]>n) break;is_prime[i*prime[j]]=false;minn_prime[i*prime[j]]=prime[j];if (i%prime[j]==0) break;}}
}int ksm(int a,int b){自己寫快速冪
}int inv[N],fac[N];void init_inv(int n){fac[0]=1;for(int i=1;i<=n;i++)fac[i]=1ll*fac[i-1]*i%mod;int tmp=ksm(fac[n],mod-2);inv[n]=1ll*fac[n-1]*tmp%mod;for(int i=n-1;i>=1;i--){tmp=1ll*tmp*(i+1)%mod;inv[i]=1ll*tmp*fac[i-1]%mod;}
}vector<pair<int,int> > prdiv;
void dp_init(int n){int cur=1;ans[0]=1;for(int i=1;i<=n;i++){prdiv.clear();int tmp=i;while (tmp!=1){int cnt=0,div=minn_prime[tmp];while (tmp%div==0){tmp/=div;cnt++;}prdiv.push_back(make_pair(div,cnt));}tmp=prdiv.size();for(int j=0;j<tmp;j++){int val=prdiv[j].first,cnt=prdiv[j].second;cur=1ll*cur*inv[1+f[val]]%mod;f[val]+=(cnt<<1);cur=1ll*cur*(1+f[val])%mod;}ans[i]=cur;for(int j=0;j<tmp;j++){int val=prdiv[j].first,cnt=prdiv[j].second;cur=1ll*cur*inv[1+f[val]]%mod;f[val]-=cnt;cur=1ll*cur*(1+f[val])%mod;}}
}int main(){get_prime(1e6);init_inv(1e6);dp_init(1e6);T=read();for(int Case=1;Case<=T;Case++){n=read();if (n==1) printf("inf\n");else printf("%d\n",ans[n-1]);}return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/79746.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/79746.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/79746.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PostgreSQL 的 pg_stat_file 函數

PostgreSQL 的 pg_stat_file 函數 pg_stat_file 是 PostgreSQL 提供的一個系統管理函數&#xff0c;用于獲取文件系統上文件的元數據信息。這個函數對于數據庫管理員進行文件級別的監控和診斷非常有用。 一 函數基本語法 pg_stat_file(filename text [, missing_ok boolean …

關于麒麟服務器實現docker-compose服務開機自啟

我本地服務器環境是麒麟V10版本&#xff1a; 首先確定docker-compose服務絕對路徑命令&#xff1a; which docker-compose我這里輸出是&#xff1a;/usr/bin/docker-compose 編輯服務文件&#xff1a; sudo vim /etc/systemd/system/docker-compose-webup.service[Unit] Desc…

基于 jQuery 實現復選框全選與選中項查詢功能

在 Web 開發中&#xff0c;復選框是常見的交互元素&#xff0c;尤其是在涉及批量操作、數據篩選等場景時&#xff0c;全選功能和選中項查詢功能顯得尤為重要。本文將介紹如何使用 HTML、CSS 和 jQuery 實現一個具備全選、反選以及選中項查詢功能的復選框組&#xff0c;幫助開發…

AfuseKt2.4.2 | 支持阿里云盤、Alist等平臺視頻播放,具備自動海報墻刮削功能的強大播放器

AfuseKt是一款功能強大的安卓端在線視頻播放器&#xff0c;支持播放阿里云盤、Alist、WebDAV等平臺的視頻內容。它具備自動海報墻刮削功能&#xff0c;能自動生成影片信息和海報墻&#xff0c;提供良好的視覺體驗。此外&#xff0c;它還支持倍速播放、字幕、音軌切換等多種實用…

Netlink在SONiC中的應用

Netlink在SONiC中的應用 Netlink介紹 Netlink 是 Linux 內核態程序與用戶空間程序之間進行通信的機制之一&#xff0c;原本是用于傳遞網絡協議棧中的各種控制消息。它采用和套接字&#xff08;socket&#xff09;編程接口相同的形式&#xff0c;常用于配置內核網絡子系統&…

語音合成之十一 提升TTS語音合成效果:低質量數據清洗、增強與數據擴增

低質量數據清洗、增強與數據擴增 1. 引言&#xff1a;TTS的基石——數據質量2. 基礎&#xff1a;TTS數據準備工作流2.1 規劃&#xff1a;定義藍圖2.2 執行&#xff1a;從原始數據到訓練就緒格式2.3 最佳實踐與可復現性 3. 攻克缺陷&#xff1a;低質量語音數據的清洗與增強3.2 手…

Java IO流分類與記憶方法

Java IO流分類與記憶方法 在Java IO流體系中,理解節點流和包裝流的區別是掌握IO編程的關鍵。 一、核心分類標準 1. 節點流(Node Stream) 直接對接數據源:直接連接物理IO設備(文件、網絡、內存等)基礎功能:提供最基礎的讀寫能力命名特征:通常包含數據源類型名稱(如Fi…

架構師如何構建個人IP:職業規劃與業務戰略的雙重提升

在數字化時代&#xff0c;軟件架構師的角色已從單純的技術專家轉變為兼具技術領導力和業務影響力的復合型人才。如何構建個人IP&#xff0c;提升行業影響力&#xff0c;成為架構師職業發展的關鍵課題。本文從個人認知、業務戰略、架構決策、產品思維四個維度&#xff0c;探討架…

vscode運行python的快捷鍵

以下是一些在 VS Code 中運行 Python 代碼的常用快捷鍵&#xff1a; 運行 Python 文件 Windows/Linux &#xff1a;Ctrl F5。此快捷鍵會直接運行當前打開的 Python 文件&#xff0c;不會自動進入調試模式。若之前有配置過終端&#xff0c;一般會使用配置好的終端來運行&…

使用OpenCV 和 Dlib 實現疲勞檢測

文章目錄 引言1.相關技術介紹2. 系統原理2.1 眼睛縱橫比(EAR)算法2.2 系統工作流程 3.代碼解析3.1 關鍵函數說明3.2 主循環邏輯 4.實際應用效果5.參數調優建議6.總結 引言 疲勞駕駛是交通事故的主要原因之一。本文將介紹如何使用Python和計算機視覺技術構建一個實時疲勞駕駛檢…

VBA實現后入先出(LIFO)庫存統計

先入先出&#xff08;FIFO&#xff09;比較容易理解&#xff0c;買入早的優先賣出。與之對應的是后人先出&#xff08;LIFO&#xff09;&#xff0c;就是優先賣出最近買入的&#xff0c;例如&#xff1a;第8行賣出2K&#xff0c;當天還沒有買入記錄&#xff0c;只能找前一天的買…

Python中的客戶端和服務端交互的基本內容

目錄 網絡協議 網絡的通信方式 需要安裝的組件和需要導入的包模塊 安裝的組件 導入包模塊 如何創建客戶端 如何創建服務端 網絡協議 IPV4&#xff1a;是互聯網協議的第四版&#xff0c;也是目前廣泛使用的網絡協議。它使用32位地址格式&#xff0c;理論上可以提供約43億…

【硬核攻堅】告別CUDA OOM!DeepSeek部署顯存瓶頸終極解決方案:三大策略高效落地

目錄 引言:大模型落地的“甜蜜”與“煩惱”DeepSeek剖析:為何它如此“吃”顯存?CUDA OOM的“幽靈”:現象、根因與診斷破局之道:三大策略馴服顯存“猛獸” 策略一:模型量化 - 給模型“瘦身”的藝術策略二:動態優化 - 榨干硬件潛能策略三:分布式擴展 - 集群的力量實戰演練…

JavaSE核心知識點01基礎語法01-01(關鍵字、標識符、變量)

&#x1f91f;致敬讀者 &#x1f7e9;感謝閱讀&#x1f7e6;笑口常開&#x1f7ea;生日快樂?早點睡覺 &#x1f4d8;博主相關 &#x1f7e7;博主信息&#x1f7e8;博客首頁&#x1f7eb;專欄推薦&#x1f7e5;活動信息 文章目錄 JavaSE核心知識點01基礎語法01-01&#xff0…

【最新Python包管理工具UV的介紹和安裝】

介紹 uv是一個非常快的 Python 包安裝程序和 pip 解析器&#xff0c;用 Rust 編寫&#xff0c;設計為pip-tools的直接替代品。 以下是官網給出的UV與其他包管理工具解決依賴&#xff08;左&#xff09;和安裝包&#xff08;右&#xff09;的對比圖。 可以看出UV是一個極快的 P…

麒麟、UOS系統在線打開word文件并提取修訂痕跡

麒麟、UOS系統在線打開word文件并提取修訂痕跡 查看本示例演示效果&#xff08;Windows版&#xff09; 查看本示例演示效果&#xff08;國產版&#xff09;本示例關鍵代碼的編寫位置&#xff0c;請參考“開始 - 快速上手”里您所使用的開發語言框架的最簡集成代碼 注意 本文中…

【SpringAI+阿里云百煉】AI對話4個Demo

基于SpringAI和阿里云百煉平臺&#xff0c;實現了四個AI對話的小Demo 小團團對話機器人哄哄模擬器培訓班智能客服仿ChatPDF 筆記如下:語雀知識筆記《SpringAI》

【數據結構】單鏈表的增刪查改

本文是小編鞏固自身而作&#xff0c;如有錯誤&#xff0c;歡迎指出&#xff01; 1.鏈表的概念 概念&#xff1a;鏈表是?種物理存儲結構上?連續、?順序的存儲結構&#xff0c;數據元素的邏輯順序是通過鏈表中的 指針鏈接次序實現的。 和之前的順序表不同&#xff0c;順序一般…

LeetCode 1128.等價多米諾骨牌對的數量:計數

【LetMeFly】1128.等價多米諾骨牌對的數量&#xff1a;計數 力扣題目鏈接&#xff1a;https://leetcode.cn/problems/number-of-equivalent-domino-pairs/ 給你一組多米諾骨牌 dominoes 。 形式上&#xff0c;dominoes[i] [a, b] 與 dominoes[j] [c, d] 等價 當且僅當 (a …

以太坊智能合約開發框架:Hardhat v2 核心功能從入門到基礎教程

一、設置項目 Hardhat 項目是安裝了 hardhat 包并包含 hardhat.config.js 文件的 Node.js 項目。 操作步驟&#xff1a; ①初始化 npm npm init -y②安裝 Hardhat npm install --save-dev hardhat③創建 Hardhat 項目 npx hardhat init如果選擇 Create an empty hardhat.…