重生之 AtCoder Regular Contest 135 T1 题解
我胡汉三又回来啦!
简单总结一下前段时间,大概就是OI失利之后学习,,,然后认真搞学习一段时间之后又慢慢松懈,,,最后还陷入了感情问题(?),,然后高考理综炸裂,,200+,,,比班级平均分都低了二十多分,,,比模拟考试最低一次都低了30几分,,,,,,唉然后就最后进了TJU。 目前是TJU算法竞赛的预备队成员,,反正结果已然如此,继续努力在这个还不错的平台继续努力~
本次是寒假在家自主训练第一天的比赛,,,atcoder还是一如既往的风格,,全是数学,,,最后比赛前几分钟想到了t1正解,最后比赛结束才写完,,,a掉了,,,剩下的题,,,要是没有题解没有讲解我就不更了,,,水平不够,,补不上。。。。
(LateX 真不咋会,,,虽然学了一小段时间,,但是平时应用还是不足)
题面:
A - Floor, Ceil - Decomposition
There is an interger X written on a blackboard. You can do the operation below any number of times (possibly zero).
· Choose an interger x written on the blackboard.
· Erase one x from the blackboard and write two ner integers
![]()
Find the maximum possible product of the integers on the blackboard after your operations,modulo 998244353
题目大意:
给定一个整数,可以将其擦掉,变成,(好丑)
然后最后使得所有留下来的数乘积最大。
数据范围:
0 ≤ X ≤ 1018
输入样例:
15
输出样例:
192
样例解释:
将15变成(7,8)
操作7,使得结果变成(3,4,8)
操作4,使得结果变成(3,2,2,8)
操作8,使得结果变成(3,2,2,4,4)
最终用3x2x2x4x4=192
输入样例2:
3
输出样例2:
3
输入样例3:
100
输出样例3:
824552442
最大的答案应该是 5856458868470016 取模后的结果如上
题解:
首先是上来思考,对于偶数n来说,拆分的两个数乘积肯定是 n2/4 简单的数学不等式知识可以证明,凡是大于4的偶数,都应该进行拆分,使得最终结果乘积变得更大,而对于4本身,拆不拆分无所谓,不影响最终结果,对于2,不能拆分,否则会使得结果变小 (显然)
然后考虑奇数,首先下取整+上取整,可以保证拆分出来的两个数的和等于原本的数,那么只需要让 2x+1 < x*(x+1) ,可以解得,对于所有大于3的奇数,都应该进行拆分,使得结果更大,而3则不需要拆分。
那么其实我们能够想到,最终留在黑板上的数字,应该是由2,3两个数字组成的序列。 (我们考虑把所有的4都拆成两个2,来对问题进行归一化)
而且刚刚还提到了一个性质,在拆分的过程中,和不变,那么就变成统计一个数能够拆分成多少个2,多少个3,然后最终结果就是快速幂取模运算。
对于这个问题,我想了很久,最终把表格列出来进行打表找规律(菜是原罪)
可以发现,,对于2的幂次来说,应该最终拆分成 x/2 个 2 和 0 个 3
我们以这样的数作为分界线(以8-16为例),可以看到,2的数量先是每个减少一个,直到0,然后再每个增加两个,直到下一个2的幂次
对于3来说,规律更加明显,对于每个2的幂次的数来说,3的个数都是0,然后先逐个+1,再逐个-1
那么最后结合快速幂,就可以得到最终正确的答案啦!
代码:
#include<bits/stdc++.h> #define re register #define ll long long #define inc(i,j,k) for(re int i=j;i<=k;i++) #define dec(i,j,k) for(re int i=j;i>=k;i--) using namespace std; inline int read() { re int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') {if(ch=='-') f=-1; ch=getchar();} while(ch>='0'&&ch<='9') {x=x*10+(ch^48); ch=getchar();} return x*f; } ll x; ll cnt2,cnt3; ll ans=1; ll mod = 998244353; ll qmm(ll a,ll b) { ll res=0; while(b) { if(b&1) res=(res+a)%mod; a<<=1; b>>=1; } return res; } ll qpm(ll x,ll p) { ll res=1; while(p) { if(p&1) res=res*x%mod; p>>=1; x=x*x%mod; } return res; } int main() { cin>>x; if(x==1) { cout<<1<<endl; return 0; } ll res=1; int cnt=0; while(1) { if(res*2<=x) { res=res*2; cnt++; } else break; } ll r=x-res; ll base=res/2; if(r<=base) { cnt2=base-r; cnt3=r; } else { cnt2=(r-base)*2; cnt3=base-(r-base); } // cout<<cnt2<<" "<<cnt3<<endl; ans=qmm(ans,qpm(2,cnt2)); ans=qmm(ans,qpm(3,cnt3)); cout<<ans<<endl; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了