【51Nod1847】奇怪的数学题
记\(f(x)=\)\(x\)的次大因数,那么\(sgcd(i,j)=f(gcd(i,j))\)。
下面来推式子:
\sum_{i=1}^n\sum_{j=1}^nsgcd(i,j)^k&=\sum_{i=1}^n\sum_{j=1}^nf(gcd(i,j))^k&记d=gcd(i,j)\\
&=\sum_{d=1}^nf(d)^k\sum_{\frac i d=1}^{\lfloor \frac n d\rfloor}\sum_{\frac j d=1}^{\lfloor \frac n d\rfloor}[gcd(\frac i d,\frac j d)=1]&f(1)=0\\
&=\sum_{d=2}^nf(d)^k\sum_{i=1}^{\lfloor \frac n d\rfloor}\sum_{j=1}^{\lfloor \frac n d\rfloor}[gcd(i,j)=1]\\
&=\sum_{d=2}^nf(d)^k(2\sum_{i=1}^{\lfloor \frac n d\rfloor}\varphi(i)-1)
\end{aligned}
\]
最后一步的括号是用欧拉函数的定义直接替换出来的。
我们发现,可以按\(\lfloor \frac n d \rfloor\)的取值数论分段,因为括号显然只受\(\lfloor \frac n d\rfloor\)的取值影响,关键是如何求\(f(x)^k\)的前缀和?
记\(S_x=\sum_{i=2}^xf(x)^k\),
令min_25中的\(g\)数组以\(s(x)=x^k\)的定义计算\(g\),考虑由\(g_{i,j-1}\)推到\(g_{i,j}\)的时候,减去的是什么?是\(s(p_j)*(g_{\lfloor\frac n {p_j}\rfloor,j-1}-g_{p_j-1,j-1})\),后面括号的部分是什么呢?恰好是那些最小质因子为\(p_j\)且除去\(p_j\)后剩余部分最小质因数不小于\(p_j\)的数的\(k\)次方之和,我们发现这些数的\(f\)值之和就是后面的括号。又因为每一个数至多被如此枚举到1次,所以对于每一个\(i\),我们把括号的值累加起来,这就是那些\([2,i]\)中非质数的\(f\)值之和;再加上\([2,i]\)中的质数的\(f\)值之和,也就是质数个数,我们就求得了\(S_i\)。
min_25真牛逼。
所以就做完了,\(g\)的初始化需要用到自然数幂求和,考虑到\(k\)比较小,可以用第二类斯特林数求解。
Sum_k(n)&=\sum_{i=1}^ni^k\\
&=\sum_{j=1}^k\begin{Bmatrix}k\\j\end{Bmatrix}\frac{{(n+1)}^\underline{j+1}}{j+1}
\end{aligned}
\]
Code
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <map>
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef map<ll,ui> mlu;
const int SQRTN=32000,LEN=1000001;
bool vis[LEN];
ui p[LEN],pcnt,pphi[LEN],s[51][51],pk[LEN];
ll n,k,sqrtn,m;
ll a[SQRTN*2],cnt,pos1[SQRTN],pos2[SQRTN];
ui g[SQRTN*2],sum[SQRTN*2],g1[SQRTN*2];
mlu record;
ui ksm(ui x,int y){
ui res=1;
for(;y;x=x*x,y>>=1)
if(y&1) res=res*x;
return res;
}
void prework(){
pphi[1]=1;
for(int i=2;i<LEN;i++){
if(!vis[i]){
p[++pcnt]=i;
pphi[i]=i-1;
}
for(int j=1;j<=pcnt&&i*p[j]<LEN;j++){
int x=i*p[j];
vis[x]=true;
if(i%p[j]==0){
pphi[x]=pphi[i]*p[j];
break;
}
pphi[x]=pphi[i]*(p[j]-1);
}
}
for(int i=2;i<LEN;i++) pphi[i]+=pphi[i-1];
s[0][0]=s[0][1]=1;
for(int i=1;i<=50;i++){
s[i][1]=1;
for(int j=2;j<=i;j++)
s[i][j]=s[i-1][j]*(ui)j+s[i-1][j-1];
}
}
inline int gp(ll x){
return x<=sqrtn?pos1[x]:pos2[n/x];
}
void Diz(){
for(ll i=1,j;i<=n;i=j+1){
j=n/(n/i);
a[++cnt]=n/i;
}
reverse(a+1,a+1+cnt);
for(int i=1;i<=cnt;i++)
if(a[i]<=sqrtn) pos1[a[i]]=i;
else pos2[n/a[i]]=i;
}
ui sumup(ll l,ll r){
ll a=l+r,b=r-l+1;
if(a&1) b/=2; else a/=2;
return (ui)a*(ui)b;
}
ui getPhi(ll n){
if(n<LEN) return pphi[n];
mlu::iterator pos=record.find(n);
if(pos!=record.end()) return pos->second;
ui res=sumup(1,n);
for(ll i=2,j;i<=n;i=j+1){
j=n/(n/i);
res-=getPhi(n/i)*(j-i+1);
}
record[n]=res;
return res;
}
ui getSumk(ll n){
ui res=0,t;
for(ll j=1;j<=k;j++){
t=1;
int md=(n-j+1)%(j+1);
for(ll i=n-j+1;i<=n+1;i++,md++)
if(!md||md==(j+1)) t*=(ui)i/(j+1);
else t*=(ui)i;
res+=t*s[k][j];
}
return res;
}
void calc_g(){
for(int i=2;i<=cnt;i++) g[i]=getSumk(a[i])-1,g1[i]=a[i]-1,sum[i]=0;
for(int j=1;j<=m;j++)
for(int i=cnt;i>=2&&a[i]>=p[j]*p[j];i--){
g1[i]-=g1[gp(a[i]/p[j])]-g1[gp(p[j]-1)];
ui delta=(g[gp(a[i]/p[j])]-g[gp(p[j]-1)]);
g[i]-=pk[j]*delta;
sum[i]+=delta;
}
}
ui calc(ll n){
return sum[gp(n)]+g1[gp(n)];
}
int main
prework();
scanf("%lld%lld",&n,&k);
sqrtn=(ll)sqrt(n);
m=upper_bound(p+1,p+1+pcnt,sqrtn)-p-1;
for(int i=1;i<=m;i++) pk[i]=ksm(p[i],k);
Diz();
calc_g();
ui ans=0,last=0,tmp;
for(ll i=2,j;i<=n;i=j+1){
j=n/(n/i);
tmp=calc(j);
ans+=(getPhi(n/i)*2-1)*(tmp-last);
last=tmp;
}
printf("%lu\n",ans);
return 0;
}
【51Nod1847】奇怪的数学题的更多相关文章
- [51nod1847]奇怪的数学题
description 51nod 求\[\sum_{i=1}^{n}\sum_{j=1}^{n}sgcd(i,j)^k\]其中\(sgcd(i,j)\)表示\(i,j\)的次大公约数,如果\(gcd ...
- 51nod1847 奇怪的数学题 (Min_25筛+第二类斯特林数)
link \(\sum_{i=1}^n\sum_{j=1}^n\mathrm{sgcd}(i,j)^k=\sum_{p=1}^ns(p)^k\sum_{i=1}^n\sum_{j=1}^n[\gcd( ...
- 【51NOD 1847】奇怪的数学题(莫比乌斯反演,杜教筛,min_25筛,第二类斯特林数)
[51NOD 1847]奇怪的数学题(莫比乌斯反演,杜教筛,min_25筛,第二类斯特林数) 题面 51NOD \[\sum_{i=1}^n\sum_{j=1}^nsgcd(i,j)^k\] 其中\( ...
- [51nod 1847]奇怪的数学题
[ 51nod 1847 ]奇怪的数学题 题目 点这里看题目. 分析 是挺奇怪的...... 以下定义质数集合为\(P\),\(p_i\)为第\(i\)个质数. 定义\(mp(x)\) ...
- 【51NOD1847】奇怪的数学题 min_25筛
题目描述 记\(sgcd(i,j)\)为\(i,j\)的次大公约数. 给你\(n\),求 \[ \sum_{i=1}^n\sum_{j=1}^n{sgcd(i,j)}^k \] 对\(2^{32}\) ...
- 【51nod1847】 奇怪的数学题
就当我是 A 了此题吧... 首先预备知识有点多(因为题目要处理的东西都挺毒瘤): 杜教筛运用(当然你可以用其他筛?) 第二类斯特林数相关定理 下降阶乘幂相关定理 min25 筛运用 好了可以关掉本题 ...
- 51NOD1847:奇怪的数学题
传送门 Sol 设 \(f(d)\) 表示 \(d\) 所有约数中第二大的,\(low_d\) 表示 \(d\) 的最小质因子 \[f(d)=\frac{d}{low_d}\] 那么 \[\sum_{ ...
- 【51nod1847】奇怪的数学题(Min_25筛+杜教筛)
题面 传送门 题解 这题有毒--不知为啥的错误调了半天-- 令\(f(i)={sgcd(i)}\),那么容易看出\(f(i)\)就是\(i\)的次大质因子,用\(i\)除以它的最小质因子即可计算 于是 ...
- 【51nod 1847】奇怪的数学题
题目描述 给出 N,K ,请计算下面这个式子: \(∑_{i=1}^N∑_{j=1}^Nsgcd(i,j)^k\) 其中,sgcd(i, j)表示(i, j)的所有公约数中第二大的,特殊地,如果gcd ...
随机推荐
- SICP读书笔记 3.3
SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...
- vue 组件-父组件传值给子组件
父组件通过属性,传值给子组件,子组件通过,props数组里的名称来接受父组件传过来的值. HTML部分: <div id="app"> <tmp1 :parent ...
- 利用saltstack一键部署多台zookeeper
以上是saltstack上面sls文件存放zookeeper的路径和文件 以上是入口文件把文件夹做成包 重要安装配置在zoo.sls,以下是该sls的内容 zookeeper: file.manage ...
- 对PBFT算法的理解
PBFT论文断断续续读了几遍,每次读或多或少都会有新的理解,结合最近的项目代码,对于共识的原理有了更清晰的认识.虽然之前写过一篇整理PBFT论文的博客,但是当时只是知道了怎么做,却不理解为什么.现在整 ...
- ubuntu下修改nginx的进程数
1. 进入nginx配置文件:vim /etc/nginx/nginx.conf2. 将events下的worker_processes 修改为 你希望的数字,保存文件并退出3. 重启nginx: s ...
- [奇葩问题] ERROR 2013 (HY000): Lost connection to MySQL server during query
查询一条耗时30s以上语句,实际为2分钟多. mysql> select version(); +------------+ | version() | +------------+ | 5.6 ...
- Django_rest_framework_版本(待验证)
简介 API版本控制可以用来在不同的客户端使用不同的行为.REST框架提供了大量不同的版本设计. 版本控制是由传入的客户端请求决定的,并且可能基于请求URL,或者基于请求头. 有许多有效的方法达到版本 ...
- Vue实现双向绑定的原理以及响应式数据
一.vue中的响应式属性 Vue中的数据实现响应式绑定 1.对象实现响应式: 是在初始化的时候利用definePrototype的定义set和get过滤器,在进行组件模板编译时实现water的监听搜集 ...
- oo第八次作业--5,6,7次作业总结
一.多线程的设计 这三次作业的主要内容就是使用多线程并且解决多线程中出现的问题.而对于多线程我也有了自己的理解.首先明确的一点是单个CPU在同一时间只能处理一件事.那么,不管是多进程还是多线程,我们的 ...
- 2018-2019-20172329 《Java软件结构与数据结构》第九周学习总结
2018-2019-20172329 <Java软件结构与数据结构>第九周学习总结 教材学习内容总结 <Java软件结构与数据结构>第十五章-图 一.图及无向图 1.图的相关概 ...