news 2026/4/28 2:13:27

UVa 12619 Just Make A Wish

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
UVa 12619 Just Make A Wish

题目描述

你有一个朋友Po\texttt{Po}Po,他有一个神奇的精灵。精灵每天会告诉Po\texttt{Po}Po一个整数GGG。如果GGG为正数,那么Po\texttt{Po}Po的土地面积会乘以GGG;如果GGG为负数,那么Po\texttt{Po}Po的土地面积会除以∣G∣|G|G(保证能整除)。初始土地面积为111。每天,你需要计算出当前土地面积对应的“不同矩形”的数量,即面积的正整数因子个数(因为矩形边长必须是正整数,且a×ba \times ba×bb×ab \times ab×a视为不同,除非a=ba = ba=b)。在DDD天结束后,输出每天因子个数的总和,并对109+710^9+7109+7取模。

输入格式

  • 第一行是测试用例数TTTT≤10T \le 10T10)。
  • 每个测试用例第一行是天数DDD1≤D≤1061 \le D \le 10^61D106)。
  • 接下来DDD行,每行一个整数GGG0<∣G∣≤1060 < |G| \le 10^60<G106)。

输出格式

  • 对于每个测试用例,输出一行Case X: sum,其中XXX是测试用例编号,sumsumsumDDD天因子个数总和对109+710^9+7109+7取模的结果。

题目分析

问题转化

每天我们需要计算当前面积AAA的正整数因子个数。
AAA的质因数分解为:
A=p1e1p2e2…pkek A = p_1^{e_1} p_2^{e_2} \dots p_k^{e_k}A=p1e1p2e2pkek
AAA的因子个数为:
div_count(A)=∏i=1k(ei+1) \texttt{div\_count}(A) = \prod_{i=1}^k (e_i + 1)div_count(A)=i=1k(ei+1)
因为每个质因子pip_ipi的指数可以从000eie_iei选择,共有ei+1e_i+1ei+1种选择,组合起来就是乘积。

动态维护

如果我们每天重新分解AAA,复杂度会非常高(因为AAA可能极大)。
注意到每天AAA只会乘以或除以一个数∣G∣|G|G,我们可以动态维护AAA的质因数分解(即每个质因子的指数),并相应地更新因子个数。

更新方法
  • 当乘以xxx时,对xxx分解质因数,对于每个质因子ppp及其指数eee
    • ppp原来的指数为old_expold\_expold_exp,新的指数new_exp=old_exp+enew\_exp = old\_exp + enew_exp=old_exp+e
    • 因子个数需要乘以new_exp+1old_exp+1\frac{new\_exp+1}{old\_exp+1}old_exp+1new_exp+1
  • 当除以xxx时,对xxx分解质因数,对于每个质因子ppp及其指数eee
    • ppp原来的指数为old_expold\_expold_exp,新的指数new_exp=old_exp−enew\_exp = old\_exp - enew_exp=old_expe
    • 因子个数需要乘以new_exp+1old_exp+1\frac{new\_exp+1}{old\_exp+1}old_exp+1new_exp+1

由于我们需要对109+710^9+7109+7取模,而模数是质数,因此可以用模逆元来处理除法。

算法步骤

  1. 预处理

    • 使用线性筛法求出每个数的最小质因子(Least Prime Factor, LPF \texttt{Least Prime Factor, LPF }Least Prime Factor, LPF),以便快速分解∣G∣|G|G
    • 预处理1112×1062\times 10^62×106的模逆元(因为指数可能很大,但指数不会超过2×1062\times 10^62×106)。
  2. 对每个测试用例

    • 初始化一个哈希表expMap存储当前面积的质因子指数,初始为空(面积111时所有指数为000)。
    • 初始化因子个数divCount = 1111的因子个数为111)。
    • 初始化总和sumWays = 0
    • 对于每一天的GGG
      • 计算val=∣G∣val = |G|val=G
      • 使用 LPF 快速分解valvalval
      • 根据GGG的正负,更新expMapdivCount
      • 将当天的divCount累加到sumWays(取模)。
    • 输出结果。

复杂度分析

  • 预处理LPF\texttt{LPF}LPF和逆元:O(MAXlog⁡log⁡MAX)O(MAX \log \log MAX)O(MAXloglogMAX),其中MAX=2×106MAX = 2\times 10^6MAX=2×106
  • 每天分解∣G∣|G|GO(log⁡∣G∣)O(\log |G|)O(logG)
  • 总复杂度:O(T⋅D⋅log⁡∣G∣)O(T \cdot D \cdot \log |G|)O(TDlogG),在D≤106D \le 10^6D106时可接受。

代码实现

// Just Make A Wish// UVa ID: 12619// Verdict: Accepted// Submission Date: 2025-12-17// UVa Run Time: 0.200s//// 版权所有(C)2025,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;typedeflonglongLL;constintMAX=2000005;// 足够大,因为 G 最大 1e6,但面积质因子可能更大constLL MOD=1000000007LL;vector<int>lpf;// 最小质因子 Least Prime Factorvector<LL>inv;// 模逆元// 快速幂取模LLmodPow(LL a,LL b){LL res=1;while(b){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}returnres;}// 预处理最小质因子和逆元voidinit(){lpf.resize(MAX,0);inv.resize(MAX,0);for(inti=2;i<MAX;i++){if(lpf[i]==0){// i 是质数lpf[i]=i;for(intj=i+i;j<MAX;j+=i){if(lpf[j]==0)lpf[j]=i;}}}// 预处理逆元: inv[x] = x^(-1) mod MODfor(inti=1;i<MAX;i++)inv[i]=modPow(i,MOD-2);}// 分解 x,返回质因子-指数的映射vector<pair<int,int>>factorize(intx){vector<pair<int,int>>res;while(x>1){intp=lpf[x];intcnt=0;while(x%p==0){x/=p;cnt++;}res.push_back({p,cnt});}returnres;}intmain(){ios::sync_with_stdio(false);cin.tie(nullptr);init();// 预处理intT;cin>>T;for(intcaseNo=1;caseNo<=T;caseNo++){intD;cin>>D;unordered_map<int,int>expMap;// 当前面积的质因子指数LL divCount=1;// 当前面积的因子个数LL sumWays=0;for(intday=0;day<D;day++){intG;cin>>G;intval=abs(G);vector<pair<int,int>>factors=factorize(val);if(G>0){// 乘以 valfor(auto&pf:factors){intp=pf.first,e=pf.second;intoldExp=expMap[p];intnewExp=oldExp+e;// 更新因子个数:除以(oldExp+1),乘以(newExp+1)divCount=divCount*inv[oldExp+1]%MOD;divCount=divCount*(newExp+1)%MOD;expMap[p]=newExp;}}else{// 除以 valfor(auto&pf:factors){intp=pf.first,e=pf.second;intoldExp=expMap[p];intnewExp=oldExp-e;divCount=divCount*inv[oldExp+1]%MOD;divCount=divCount*(newExp+1)%MOD;expMap[p]=newExp;}}sumWays=(sumWays+divCount)%MOD;}cout<<"Case "<<caseNo<<": "<<sumWays<<"\n";}return0;}

关键点总结

  1. 因子个数的公式∏(ei+1)\prod (e_i + 1)(ei+1)
  2. 动态维护:通过维护质因子指数,避免对大数直接分解。
  3. 模逆元:因为模数是质数,可以用费马小定理求逆元,从而在模意义下做除法。
  4. 预处理LPF\texttt{LPF}LPF:快速分解∣G∣|G|G,是算法高效的关键。

这样,即使DDD高达10610^6106,算法也能在合理时间内运行完毕。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/21 15:56:57

UVa 1420 Priest John‘s Busiest Day

题目描述 John\texttt{John}John 是小镇上唯一的牧师。每年的 101010 月 262626 日是他最忙碌的一天&#xff0c;因为传说在这一天结婚的夫妇会受到爱神的祝福。今年有 NNN 对夫妇计划在这一天举行婚礼&#xff0c;第 iii 对夫妇的婚礼计划在时间 SiS_iSi​ 到 TiT_iTi​ 进行。…

作者头像 李华
网站建设 2026/4/19 20:41:14

WordPress支持跨平台ppt图片压缩转存

要求&#xff1a;开源&#xff0c;免费&#xff0c;技术支持 博客&#xff1a;WordPress 开发语言&#xff1a;PHP 数据库&#xff1a;MySQL 功能&#xff1a;导入Word,导入Excel,导入PPT(PowerPoint),导入PDF,复制粘贴word,导入微信公众号内容,web截屏 平台&#xff1a;Window…

作者头像 李华
网站建设 2026/4/22 15:36:43

2、Linksys WRT54G路由器:开源固件历史、硬件特性与版本差异

Linksys WRT54G路由器:开源固件历史、硬件特性与版本差异 在网络设备的世界里,Linksys WRT54G系列路由器以其可定制性和开源特性受到众多爱好者的青睐。下面我们将深入了解其开源固件的历史、硬件特性以及不同版本之间的差异。 1. WRT54G开源固件的历史 2003年初,Andrew …

作者头像 李华
网站建设 2026/4/17 20:21:50

5、Linksys WRT54G路由器第三方固件全解析

Linksys WRT54G路由器第三方固件全解析 在网络设备的使用中,路由器固件的选择至关重要。对于Linksys WRT54G系列路由器,有多种第三方固件可供选择,每种固件都有其独特的特点和适用场景。下面将详细介绍几种常见的第三方固件。 Linksys原始固件 背景 :该固件是整个WRT54…

作者头像 李华
网站建设 2026/4/26 22:51:08

Qt地图集成实战:高德插件让开发效率提升300%

还在为Qt应用添加地图功能而烦恼吗&#xff1f;传统方案要么依赖笨重的浏览器内核&#xff0c;要么开发周期长、维护困难。今天&#xff0c;我将分享如何通过高德地图Qt插件&#xff0c;在3分钟内完成专业级地图集成&#xff0c;让开发效率实现质的飞跃。 【免费下载链接】amap…

作者头像 李华
网站建设 2026/4/23 11:17:41

ExoPlayer实时流性能测试:从入门到精通的完整指南

ExoPlayer实时流性能测试&#xff1a;从入门到精通的完整指南 【免费下载链接】ExoPlayer 项目地址: https://gitcode.com/gh_mirrors/ex/ExoPlayer ExoPlayer作为Android平台上领先的媒体播放解决方案&#xff0c;在实时流媒体场景中展现出色的性能表现。本指南将深入…

作者头像 李华