【51nod1965】奇怪的式子
Solution
怎么说呢。。这题。。做的有点痛苦。。
首先看这个式子长得。。比较奇怪,指数里面那个加号有点烦人,而且这个函数不是一个积性函数也有点烦人,那就考虑把这个函数拆成两部分来算
\]
首先看第一部分的处理,我们记\(Sum(i)=\frac{n(n+1)}{2}\),那么有:
&\prod\limits_{i=1}^{n}\sigma_0(i)^i=\prod\limits_{p}\prod\limits_{k}(k+1)^W\\
&W=p^k\cdot Sum(\lfloor \frac{n}{p^k}\rfloor)-p^{k+1}\cdot Sum(\lfloor \frac{n}{p^k+1}\rfloor)\\
\end{aligned}
\]
具体一点的话就是,因为这里是连乘,然后\(\sigma_0(x)\)是一个积性函数,所以我们考虑将每一个\(i\)分解质因数,然后按照分解的质因数把每个\(\sigma_0\)写开
那么,枚举素数\(p\),枚举这个素数的指数\(k\),然后统计分解质因数后\(p\)的指数恰好为\(k\)的数的个数,然后算贡献就好了
然而这个式子还是不能直接用来求解第一部分的答案,所以我们还要进一步处理
考虑分成\(p<=\sqrt n\)和\(p>\sqrt n\)两类来看:
首先对于\(p<=\sqrt n\)的部分,是可以直接计算而不会T掉的
然后对于\(p>\sqrt n\)的部分,\(p\)的指数\(k\)只能是\(1\)(因为\(p>\sqrt n\)),所以:
&\prod\limits_{p>\sqrt n}\prod\limits_{k}(k+1)^W=\prod\limits_{p>\sqrt n}2^{W'}\\
&W'=Sum(\lfloor \frac{n}{p} \rfloor)\\
\end{aligned}
\]
这个部分的话,因为\(\lfloor \frac{n}{p}\rfloor\)的取值只有\(2\sqrt n\)个,所以我们可以直接用莫比乌斯反演中的那个常用技巧,分块一下求就可以了
然后整个过程中我们需要预先处理出来的东西有两个:约数个数和约数和
这两个东西用min_25筛一下就好了
然而!
这样我们求出来的是\(2\)的指数部分,这个数在计算的过程中如果不加取模操作的话会奇大无比,这就很尴尬
注意到题目中的模数是一个素数,那么我们可以用一下由欧拉定理得到的一个结论:
\]
也就是说我们可以对指数部分的计算\(\%\phi(p)\)(也就是\(p-1\)),并不会影响结果,问题解决ovo
然后看第二部分,这一个部分看上去会比较麻烦(实际上也确实有点麻烦)
把式子单独列出来:
\]
首先来分析一下什么样的\(i\)才会被算进去
由于\(\mu(i)\)有一个很好的性质:当\(i\)有平方因子的时候\(\mu(i)=0\),所以我们接下来对\(i\)的讨论可以多一个前提就是\(i\)分解质因数之后每一个素数的指数都是\(1\)
那么沿用处理第一部分的时候的想法,我们将每个\(i\)分解质因数拆开来写
用\(d(i)\)表示\(i\)的质因数个数,那么可以得到:
\]
有了上面的欧拉定理得到的结论支撑,我们就可以放心大胆地先求指数再求结果啦
用类似min_25筛中设状态的方式:
记\(minp(i)\)表示\(i\)的最小质因子,\(d(i)\)表示\(i\)的质因数个数,\(P\)为素数列表
首先大力定义
\]
然后为了方便转移我们还需要定义一个辅助数组
\]
那么我们可以得到转移:
&f1(i,j)=f1(i,j+1)+(-1)*(f1(\lfloor \frac{n}{P_j}\rfloor,j+1)-f1(P_j,j+1))\\
&f(i,j)=f(i,j+1)+(-1)*(f(\lfloor \frac{n}{P_j}\rfloor,j+1)-f(P_j,j+1))+(-1)*(f1(\lfloor \frac{n}{P_j}\rfloor,j+1)-f1(P_j,j+1))
\end{aligned}
\]
初始化\(f1(i,max)=f(i,max)=(-1)*[1,i]\)范围内素数个数,\(max\)表示的是\(>=\sqrt n\)的第一个素数在列表中的下标
具体一点的话就是,首先所有的\((-1)\)其实都是\(\mu (p)\)的值,因为是素数的\(\mu\)值所以是\(-1\)
然后转移的话其实就是要加上\([1,i]\)范围内的\(minp(x)=P_j\)的数的贡献,为了保证有\(P_j\)的存在并且是最小的,所以调用的是\(f(\lfloor\frac{n}{P_j}\rfloor,j+1)\)和\(f1(\lfloor\frac{n}{P_j}\rfloor,j+1)\),然后还要保证素数不会被多算一次所以要去掉素数部分也就是\(f(P_j,j+1)\)和\(f1(P_j,j+1)\)
然后就可以快乐dp得出答案啦
一些实现的细节问题:
1.这题的模数比较巨大,两个数的乘积可能爆long long,所以要。。用一个奇妙黑科技,也就是用long double 模拟取模这样来取模qwq
2.注意在算的过程中的模数到底是用\(\phi(MOD)\)还是\(MOD\)要看清楚。。调了好久。。
3.在求的过程中因为数字都比较巨大所以。。要积极取模
(调试调到后来直接放弃思考见到乘号就取模导致代码长得十分不可描述并且常数巨大qwq)
代码大概长这个样子
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
#define ld long double
using namespace std;
const int MAXN=1e6+10;
const ll MOD=1e12+39,PHIMOD=MOD-1;
ll pcnt[MAXN*2],psum[MAXN*2],g[MAXN*2],f[MAXN*2],f1[MAXN*2];
ll P[MAXN],rec[MAXN*2];
int loc1[MAXN],loc2[MAXN];
bool vis[MAXN];
ll n,m,sq,cnt,cntval,ans,T;
void prework(int n);
void init_loc();
void get_g();
int Pos(ll x){return x<=sq?loc1[x]:loc2[n/x];}
ll Sum(ll l,ll r);
ll ksm(ll x,ll y);
ll mul(ll x,ll y,ll mod){
ld tmp=(ld)x*(ld)y;
return (x*y-((ll)(tmp/(ld)mod)*mod)+mod)%mod;
}
void solve1();
void solve2();
int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
scanf("%d",&T);
prework(MAXN);
for (int o=1;o<=T;++o){
scanf("%lld",&n);
sq=sqrt(n)+0.5;
m=upper_bound(P+1,P+1+cnt,sq)-P-1;
init_loc();
get_g();
ans=1;
solve1();
solve2();
printf("%lld\n",ans);
}
}
void prework(int n){
cnt=0;
for (int i=2;i<=n;++i){
if (!vis[i])
P[++cnt]=i;
for (int j=1;j<=cnt&&P[j]*i<=n;++j){
vis[i*P[j]]=true;
if (i%P[j]==0) break;
}
}
}
void init_loc(){
cntval=0;
for (ll i=1,pos;i<=n;i=pos+1){
rec[++cntval]=n/i;
pos=n/(n/i);
}
reverse(rec+1,rec+1+cntval);
for (int i=1;i<=cntval;++i)
if (rec[i]<=sq) loc1[rec[i]]=i;
else loc2[n/rec[i]]=i;
}
void get_g(){
for (int i=1;i<=cntval;++i)
pcnt[i]=rec[i]-1,psum[i]=Sum(1,rec[i])-1;
for (int j=1;j<=m;++j)
for (int i=cntval;i>=1&&rec[i]>=1LL*P[j]*P[j];--i){
pcnt[i]-=pcnt[Pos(rec[i]/P[j])]-pcnt[Pos(P[j]-1)];
psum[i]=(psum[i]+PHIMOD-P[j]*(psum[Pos(rec[i]/P[j])]+PHIMOD-psum[Pos(P[j]-1)])%PHIMOD)%PHIMOD;
}
}
ll Sum(ll l,ll r){
ll tmp=l+r,tmp1=r-l+1;
if (tmp&1) tmp1/=2;
else tmp/=2;
return mul(tmp,tmp1,PHIMOD);
}
ll ksm(ll x,ll y){
ll ret=1,base=x;
for (;y;y>>=1,base=mul(base,base,MOD))
if (y&1) ret=mul(ret,base,MOD);
return ret;
}
void solve1(){//\prod \sigma i^i
ll tmp;
for (int i=1;i<=m;++i){
tmp=P[i];
for (int k=1;tmp<=n;tmp*=P[i],++k)
ans=mul(ans,ksm(k+1,(tmp*Sum(1,n/tmp)%PHIMOD-tmp*P[i]%PHIMOD*Sum(1,n/(tmp*P[i]))%PHIMOD)+PHIMOD)%PHIMOD,MOD);
}
tmp=0;
for (int i=Pos(sq)+1;i<=cntval;++i)
tmp+=mul(Sum(1,n/rec[i]),(psum[i]-psum[i-1]+PHIMOD)%PHIMOD,PHIMOD);
ans=mul(ans,ksm(2,tmp),MOD);
}
void solve2(){//\prod \sigma i^{\mu i}
for (int i=2;i<=cntval;++i) f1[i]=f[i]=PHIMOD-pcnt[i];
for (int j=m;j>=1;--j){
for (int i=cntval;i>=2&&rec[i]>=P[j]*P[j];--i){
f1[i]=(f1[i]+(-1LL)*(f1[Pos(rec[i]/P[j])]-f1[Pos(P[j])]))%PHIMOD;
f[i]=(f[i]+(-1LL)*(f[Pos(rec[i]/P[j])]-f[Pos(P[j])])+(-1LL)*(f1[Pos(rec[i]/P[j])]-f1[Pos(P[j])]))%PHIMOD;
if (f1[i]<0) f1[i]+=PHIMOD;
if (f[i]<0) f[i]+=PHIMOD;
}
}
ans=mul(ans,ksm(2,f[Pos(n)]),MOD);
}
【51nod1965】奇怪的式子的更多相关文章
- [51nod1965]奇怪的式子
noteskey 怎么说,魔性的题目...拿来练手 min_25 正好...吧 首先就是把式子拆开来算贡献嘛 \[ANS=\prod_{i=1}^n \sigma_0(i)^{\mu(i)} \pro ...
- 51nod1965. 奇怪的式子(min_25筛)
题目链接 http://www.51nod.com/Challenge/Problem.html#!#problemId=1965 题解 需要求的式子显然是个二合一形式,我们将其拆开,分别计算 \(\ ...
- 【51NOD1965】奇怪的式子 min_25筛
题目描述 给你\(n\),求 \[ \prod_{i=1}^n{\sigma_0(i)}^{i+\mu(i)} \] 对\({10}^{12}+39\)取模. \(\sigma_0(i)\)表示约数个 ...
- 51NOD1965:奇怪的式子
传送门 拆开变成 \[\prod_{i=1}^{n}\sigma_0(i)^{\mu(i)}\prod_{i=1}^{n}\sigma_0(i)^{i}\] 考虑 \(\prod_{i=1}^{n}\ ...
- 51nod 1965 奇怪的式子 —— min_25筛
题目:http://www.51nod.com/Challenge/Problem.html#!#problemId=1965 推式子就同这里:https://www.cnblogs.com/yoyo ...
- 51nod 1965 奇怪的式子——min_25筛
题目:http://www.51nod.com/Challenge/Problem.html#!#problemId=1965 考虑 \( \prod_{i=1}^{n}\sigma_0^i \) \ ...
- light oj 1236 分解质因数
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=70017#problem/H 题意:求满足1<=i<=j<=n ...
- BZOJ 1045 糖果传递
奇怪的式子.最后发现取中位数. #include<iostream> #include<cstdio> #include<cstring> #include< ...
- BZOJ3456城市规划
题目描述 刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了.刚才说过, 阿狸的国家有n个城市, 现在国家需要在某些城市对之间建立一些贸易路线, 使得整个国家的任意两个城市都直接或间接的连通.为了 ...
随机推荐
- oracle的分号和斜杠/
;是执行语句必须的/是执行语句块必须的 比如执行一个触发器 CREATE OR REPLACE TRIGGER "TRG_1" BEFORE INSERT ON "CAT ...
- ZT-----用javascrip写一个区块链
几乎每个人都听说过像比特币和以太币这样的加密货币,但是只有极少数人懂得隐藏在它们背后的技术.在这篇博客中,我将会用JavaScript来创建一个简单的区块链来演示它们的内部究竟是如何工作的.我将会称之 ...
- TW实习日记:第九天
这两天有点忙,要改前端网页和加需求上去.所以昨天说的Vue缓存机制也没看,所以打算现在列个挖了的坑的清单: Vue缓存机制.生命周期和钩子函数 使用项目组自用组件来重写静态页面 SSM框架搭建.整合流 ...
- python sys.argv是什么?
1.sys.argv 是获取运行python文件的时候命令行参数,且以list形式存储参数 2.sys.argv[0] 代表当前module的名字 下面的代码文件是a.py,当我不用IDE工具,只用命 ...
- New York Comic Con 2013 - 2013年纽约动漫展
New York Comic Con - 2013年纽约动漫展 New York Comic Con is the largest pop culture event on the East Coas ...
- mysql 转换13位数字毫秒时间
MySQL毫秒值和日期转换,MYSQL内置函数FROM_UNIXTIME: select FROM_UNIXTIME(t.createDate/1000,'%Y-%m-%d %h:%i:%s') as ...
- 浅谈TSM概念、系统架构及技术发展
NFC作为一种近距离的无线通信技术,提供了一种更直接.更安全的现场交互解决方案.它能够允许电子设备之间进行非接触式点对点数据传输,实现数据交换.访问内容与服务.有了它,手机不再只是打电话.发短信以及上 ...
- 经验之谈:10位顶级PHP大师的开发原则
导读:在Web开发世界里,PHP是最流行的语言之一,从PHP里,你能够很容易的找到你所需的脚本,遗憾的是,很少人会去用“最佳做法”去写一个PHP程序.这里,我们向大家介绍PHP的10种最佳实践,当然, ...
- CSS3 使用 calc() 计算高度 vh px
Viewport viewport:可视窗口,也就是浏览器. vw Viewport宽度, 1vw 等于viewport宽度的1% vh Viewport高度, 1vh 等于view ...
- Team Work总结 && OPP课程总结
团队作业总结 工作总结 本次大作业我在团队内的工作是:根据框架构建实现建筑类的功能,包括防御塔.水晶.泉水等建筑.根据架构框架以及结合各建筑的特点,利用继承和多态很快速的解决了一些基本的问题.然而在实 ...