51nod 1847 奇怪的数学题

本文深入探讨了Min_25筛算法,一种高效计算积性函数前缀和的方法。通过定义和推导,文章详细解释了如何利用最小素因子筛选技术优化计算过程,并给出了具体的实现代码。适用于算法竞赛和高级数学应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于min_25筛:

现在有一个积性函数,对素数 p p p f ( p ) = a p i f(p)=ap^i f(p)=api,我想求出他的前缀和。

m i n p ( x ) minp(x) minp(x)表示 x x x最小的素因子。
q ( n , j ) = ∑ i = 1 n [ m i n p ( x ) ≥ p j ] f ( i ) q(n,j)=\sum_{i=1}^n[minp(x)\ge p_j]f(i) q(n,j)=i=1n[minp(x)pj]f(i),即最小素因子不小于第 j j j个素数 p j p_j pj f f f值的和。
由于 q ( n , j ) q(n,j) q(n,j) q ( n , j + 1 ) q(n,j+1) q(n,j+1)多出来的只有 m i n p ( x ) = p j minp(x)=p_j minp(x)=pj的部分,有:
q ( n , j ) = q ( n , j + 1 ) + ∑ i = 1 p j i ≤ n q ( ⌊ n p j i ⌋ , j + 1 ) f ( p j i ) + ∑ i = 1 p j i ≤ n f ( p j i ) q(n,j)=q(n,j+1)+\sum_{i=1}^{p_j^i\le n}q(\lfloor \frac n {p_j^i}\rfloor,j+1)f(p_j^i)+\sum_{i=1}^{p_j^i\le n}f(p_j^i) q(n,j)=q(n,j+1)+i=1pjinq(pjin,j+1)f(pji)+i=1pjinf(pji)
注意到 q ( n , j ) q(n,j) q(n,j)中,最小的合数为 p j 2 p_j^2 pj2,故对于 p j 2 > n p_j^2>n pj2>n的情况,有:
q ( n , j ) = ∑ i = j p i ≤ n f ( p i ) q(n,j)=\sum_{i=j}^{p_i\le n}f(p_i) q(n,j)=i=jpinf(pi)

g ( n , j ) = ∑ i = 1 n [ i ∈ p r i m e ∨ m i n p ( i ) > p j ] f ( i ) g(n,j)=\sum_{i=1}^n[i\in prime \lor minp(i)>p_j]f(i) g(n,j)=i=1n[iprimeminp(i)>pj]f(i),即不大于 n n n的所有素数的 f f f值和最小素因子大于 p j p_j pj的合数的 f f f值的和。
z z z为最大的满足 p z 2 ≤ n p_z^2\le n pz2n的值,即第 z z z个素数是最大的不大于 ⌊ n ⌋ \lfloor \sqrt n\rfloor n 的素数,则 g ( n , p z ) g(n,pz) g(n,pz)表示不大于 n n n的所有素数的 f f f值的和。
由于 g ( n , j ) g(n,j) g(n,j) g ( n , j − 1 ) g(n,j-1) g(n,j1)减少的只有 m i n p ( x ) = p j minp(x)=p_j minp(x)=pj的合数的部分,有:
g ( n , j ) = g ( n , j − 1 ) − ( g ( ⌊ n p j ⌋ , j − 1 ) − ∑ i = 1 j − 1 f ( p i ) ) f ( p j ) g(n,j)=g(n,j-1)-(g(\lfloor \frac n {p_j} \rfloor,j-1)-\sum_{i=1}^{j-1}f(p_i))f(p_j) g(n,j)=g(n,j1)(g(pjn,j1)i=1j1f(pi))f(pj)
同时,当 p j 2 > n p_j^2>n pj2>n时,容易得:
g ( n , j ) = g ( n , j − 1 ) g(n,j)=g(n,j-1) g(n,j)=g(n,j1)
以此,我们便可以计算出 p j 2 > n p_j^2>n pj2>n时的 q q q值,即:
q ( n , j ) = g ( n , j ) − ∑ i = 1 j − 1 f ( p i ) = g ( n , p z ) − ∑ i = 1 j − 1 f ( p i )   ∣ n ≥ p j q ( n , j ) = 0   ∣ n &lt; p j q(n,j)=g(n,j)-\sum_{i=1}^{j-1}f(p_i)=g(n,pz)-\sum_{i=1}^{j-1}f(p_i)\ |n\ge p_j\\ q(n,j)=0\ |n &lt; p_j q(n,j)=g(n,j)i=1j1f(pi)=g(n,pz)i=1j1f(pi) npjq(n,j)=0 n<pj
(需要注意的是,在 g g g的递推式中我们将 f f f当作一个完全积性函数,此时我们设 g g g的边界 g ( n , 0 ) = ∑ i = 1 n f ( i ) g(n,0)=\sum_{i=1}^nf(i) g(n,0)=i=1nf(i),容易证明最终计算出的 g ( n , p z ) g(n,pz) g(n,pz)是正确的。故当 f f f是一个包含常数个项的多项式时,需要将每一项分别计算,否则结果将是错误的,除非能够证明 f f f本身就是一个完全积性函数。)

计算 g g g的复杂度为:(我tm怎么知道怎么算)
∑ i = 1 n n l n n + n i l n n i = O ( n 3 4 l n n ) \sum_{i=1}^{\sqrt n}\frac {\sqrt n} {ln {\sqrt n}}+\frac {\sqrt {\frac n i}} {ln{\sqrt {\frac n i}}}=O(\frac {n^{\frac 3 4}} {lnn}) i=1n lnn n +lnin in =O(lnnn43)
计算 q q q的复杂度为:(因为连式子都不会写所以直接写答案好了) O ( n 3 4 l n n ) O(\frac {n^{\frac 3 4}} {lnn}) O(lnnn43)

题目

枚举gcd,有:
a n s = ∑ i = 1 n ( i m i n p ( i ) ) k F ( ⌊ n i ⌋ ) F ( x ) = ∑ i = 1 x ∑ j = 1 x [ ( i , j ) = 1 ] 1 ans=\sum_{i=1}^n(\frac i {minp(i)})^kF(\lfloor \frac n i\rfloor)\\ F(x)=\sum_{i=1}^x\sum_{j=1}^x[(i,j)=1]1 ans=i=1n(minp(i)i)kF(in)F(x)=i=1xj=1x[(i,j)=1]1
F F F很好求,考虑如何求 ( i m i n p ( i ) ) k (\frac i {minp(i)})^k (minp(i)i)k的前缀和。
设:
g ( n ) = ∑ i = 1 n [ i ∈ p r i m e ] i g ′ ( n ) = ∑ i = 1 n [ i ∈ p r i m e ] i k q ( n , j ) = ∑ i = 1 n [ m i n p ( i ) ≥ p j ] i k q ′ ( n , j ) = ∑ i = 1 n [ m i n p ( i ) ≥ p j ] ( i m i n p ( i ) ) k g(n)=\sum_{i=1}^n[i\in prime]i\\ g&#x27;(n)=\sum_{i=1}^n[i\in prime]i^k\\ q(n,j)=\sum_{i=1}^n[minp(i)\ge p_j]i^k\\ q&#x27;(n,j)=\sum_{i=1}^n[minp(i)\ge p_j](\frac i {minp(i)})^k g(n)=i=1n[iprime]ig(n)=i=1n[iprime]ikq(n,j)=i=1n[minp(i)pj]ikq(n,j)=i=1n[minp(i)pj](minp(i)i)k
有:
q ( n , j ) = q ( n , j + 1 ) + ∑ d = 1 p j d ≤ n ( 1 + q ( ⌊ n p j d ⌋ , j + 1 ) ) p j d k q ′ ( n , j ) = q ′ ( n , j + 1 ) + ∑ d = 1 p j d ≤ n ( 1 + q ( ⌊ n p j d ⌋ , j + 1 ) ) p j ( d − 1 ) k q ′ ( n , j ) = M A X { 0 , g ( n ) − j + 1 } ∣ p j 2 &gt; n q ( n , j ) = M A X { 0 , g ′ ( n ) − ∑ i = 1 j − 1 p i } ∣ p j 2 &gt; n q(n,j)=q(n,j+1)+\sum_{d=1}^{p_j^d\le n}(1+q(\lfloor \frac n {p_j^d}\rfloor,j+1))p_j^{dk}\\ q&#x27;(n,j)=q&#x27;(n,j+1)+\sum_{d=1}^{p_j^d\le n}(1+q(\lfloor \frac n {p_j^d}\rfloor,j+1))p_j^{(d-1)k}\\ q&#x27;(n,j)=MAX\{0,g(n)-j+1\}|p_j^2&gt;n\\ q(n,j)=MAX\{0,g&#x27;(n)-\sum_{i=1}^{j-1}p_i\}|p_j^2&gt;n q(n,j)=q(n,j+1)+d=1pjdn(1+q(pjdn,j+1))pjdkq(n,j)=q(n,j+1)+d=1pjdn(1+q(pjdn,j+1))pj(d1)kq(n,j)=MAX{0,g(n)j+1}pj2>nq(n,j)=MAX{0,g(n)i=1j1pi}pj2>n
g g g g ′ g&#x27; g可以用min_25筛计算, q q q q ′ q&#x27; q直接递推即可(当然他们长得其实和min_25筛一样)。

至于如何在不能用逆元的情况下求 ∑ i = 1 n i k \sum_{i=1}^ni^k i=1nik,也就是 g ′ ( n , 0 ) g&#x27;(n,0) g(n,0)
s ( n , k ) s(n,k) s(n,k)表示将 n n n个不同的球放进 k k k个相同的箱子的方案数,即第二类斯特林数。
由其组合性质,有:
n k = ∑ i = 1 n ( n i ) s ( k , i ) i ! ∑ i = 1 n i k = ∑ i = 1 n ∑ j = 1 i ( i j ) s ( k , j ) j ! = ∑ j = 1 n s ( k , j ) j ! ∑ k = 1 n ( k j ) = ∑ j = 1 n s ( k , j ) j ! ( k + 1 j + 1 ) = ∑ j = 1 n s ( k , j ) ( k + 1 ) j + 1 ‾ j + 1 n^k=\sum_{i=1}^n\binom n i s(k,i)i!\\ \sum_{i=1}^ni^k=\sum_{i=1}^n\sum_{j=1}^i\binom i js(k,j)j!\\ =\sum_{j=1}^ns(k,j)j!\sum_{k=1}^n\binom k j\\ =\sum_{j=1}^ns(k,j)j!\binom {k+1} {j+1}\\ =\sum_{j=1}^ns(k,j)\frac {(k+1)^{\underline {j+1}}} {j+1} nk=i=1n(in)s(k,i)i!i=1nik=i=1nj=1i(ji)s(k,j)j!=j=1ns(k,j)j!k=1n(jk)=j=1ns(k,j)j!(j+1k+1)=j=1ns(k,j)j+1(k+1)j+1
这样就可以无视逆元 O ( k 2 ) O(k^2) O(k2)求出结果了。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<climits>
#include<cstdio>
#include<cmath>
using namespace std;
#define clr(a) memset(a,0,sizeof(a))
//--Container
//--
typedef unsigned int ui;typedef long long ll;
const int up=1e6;const int dup=5e4;
ui strl[51][51];
bool bd[up+10];int n,dk,pn,pr[up+10],moi[up+10];ui prs[dup+10],moip[up+10];
void _init(){
    int i,j,k,d,t;for(pn=0,moi[1]=1,i=2;i<=up;++i){
        if(!bd[i]){pr[++pn]=i;moi[i]=i-1;}
        for(j=1;j<=pn&&(ll)pr[j]*i<=up;++j){
            bd[pr[j]*i]=1,moi[pr[j]*i]=moi[i]*(pr[j]-1);
            if(!(i%pr[j])){
                moi[pr[j]*i]=moi[i]*pr[j];break;
            }
        }
    }
    for(strl[0][0]=1,i=1;i<=50;++i)for(j=1;j<=i;++j)
        strl[i][j]=strl[i-1][j-1]+strl[i-1][j]*j;
    for(moip[1]=1,i=2;i<=up;++i)moip[i]+=moip[i-1]+(moi[i]<<1);
};
ui _qni(ui a,int b){
    ui r=1;for(;b;b>>=1,a*=a)if(b&1)r*=a;
    return r;
};
ui _dom(ui n,ui i){
    ui rs=1;int j;for(j=0;j<i;++j,--n)rs*=((n%i)?n:n/i);
    return rs;
};
ui _prnm(int n){
    ui rs=0;int i,j;for(i=1;i<=min(dk,n);++i)rs+=strl[dk][i]*_dom(n+1,i+1);
    return rs;
};

ui psm[(dup<<1)+10],pssm[(dup<<1)+10];int id[2][dup+10],mg[(dup<<1)+10],dn,pz,dt;
inline int _id(int x){return x<=dn?id[0][x]:id[1][n/x];};
void _genid(){
    int b,e,z;for(dn=sqrt(n),dt=0,b=1;b<=n;b=e+1){
        e=n/(n/b);z=n/e;if(z<=dn)id[0][z]=++dt;
        else
            id[1][n/z]=++dt;
        mg[dt]=z;
    }
};
void _ps(){
    int i,j,k,d,t,z;for(i=1;i<=pn&&pr[i]*pr[i]<=n;++i)prs[i]+=prs[i-1]+_qni(pr[i],dk);pz=i-1;
    for(i=1;i<=dt;++i)psm[i]=mg[i]-1,pssm[i]=_prnm(mg[i])-1;
    for(i=1;i<=pz;++i)for(z=pr[i]*pr[i],j=1;j<=dt&&z<=mg[j];++j){
        psm[j]-=(psm[_id(mg[j]/pr[i])]-i+1);
        pssm[j]-=(prs[i]-prs[i-1])*(pssm[_id(mg[j]/pr[i])]-prs[i-1]);
    }
};
ui dsm[(dup<<1)+10],dssm[(dup<<1)+10];
inline ui _dsm(int x,int j){
    return pr[j]*pr[j]>x?(x>pr[j-1]?pssm[_id(x)]-prs[j-1]:0):dsm[_id(x)];
};
inline ui _dssm(int x,int j){
    return pr[j]*pr[j]>x?(x>pr[j-1]?psm[_id(x)]-j+1:0):dssm[_id(x)];
};
void _ds(){
    int i,j,z;ui t,d;ll k;for(i=pz;i;--i)for(z=pr[i]*pr[i],j=1;j<=dt&&z<=mg[j];++j){
        t=prs[i]-prs[i-1],k=pr[i],d=1;dsm[j]=_dsm(mg[j],i+1),dssm[j]=_dssm(mg[j],i+1);
        for(;k<=mg[j];t*=(prs[i]-prs[i-1]),k*=pr[i],d*=(prs[i]-prs[i-1])){
            dsm[j]+=_dsm(mg[j]/k,i+1)*t+t;
            dssm[j]+=_dsm(mg[j]/k,i+1)*d+d;
        }
    }
};

ui mem[dup+10];
inline ui _mem(int x){return x<=up?moip[x]:mem[_id(x)];};
void __mem(int x){
    int i,j,b,e,z,t;ui rs=(ui)x*x;for(b=2;b<=x;b=e+1){
        e=x/(x/b);rs-=_mem(x/e)*(e-b+1);
    }
    mem[_id(x)]=rs;
};
void _me(){
    int i,j,k,d,t;for(i=1;mg[i]>up;++i);for(--i;i;__mem(mg[i--]));
};

void cl(){
    int i,j,k,b,e;scanf("%d %d",&n,&dk);ui rs=0;
    _init();_genid();_ps();_ds();_me();
    for(b=2;b<=n;b=e+1){
        e=n/(n/b);rs+=(_dssm(e,1)-_dssm(b-1,1))*_mem(n/e);
    }
    printf("%u\n",rs);
};

int main(){
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
#endif
    cl();
    return 0;
};
《餐馆点餐管理系统——基于Java和MySQL的课程设计解析》 在信息技术日益发达的今天,餐饮行业的数字化管理已经成为一种趋势。本次课程设计的主题是“餐馆点餐管理系统”,它结合了编程语言Java和数据库管理系统MySQL,旨在帮助初学者理解如何构建一个实际的、具有基本功能的餐饮管理软件。下面,我们将深入探讨这个系统的实现细节及其所涉及的关键知识点。 我们要关注的是数据库设计。在“res_db.sql”文件中,我们可以看到数据库的结构,可能包括菜品表、订单表、顾客信息表等。在MySQL中,我们需要创建这些表格并定义相应的字段,如菜品ID、名称、价格、库存等。此外,还要设置主键、外键来保证数据的一致性和完整性。例如,菜品ID作为主键,确保每个菜品的唯一性;订单表中的顾客ID和菜品ID则作为外键,与顾客信息表和菜品表关联,形成数据间的联系。 接下来,我们来看Java部分。在这个系统中,Java主要负责前端界面的展示和后端逻辑的处理。使用Java Swing或JavaFX库可以创建用户友好的图形用户界面(GUI),让顾客能够方便地浏览菜单、下单。同时,Java还负责与MySQL数据库进行交互,通过JDBC(Java Database Connectivity)API实现数据的增删查改操作。在程序中,我们需要编写SQL语句,比如INSERT用于添加新的菜品信息,SELECT用于查询所有菜品,UPDATE用于更新菜品的价格,DELETE用于删除不再提供的菜品。 在系统设计中,我们还需要考虑一些关键功能的实现。例如,“新增菜品和价格”的功能,需要用户输入菜品信息,然后通过Java程序将这些信息存储到数据库中。在显示所有菜品的功能上,程序需要从数据库获取所有菜品数据,然后在界面上动态生成列表或者表格展示。同时,为了提高用户体验,可能还需要实现搜索和排序功能,允许用户根据菜品名称或价格进行筛选。 另外,安全性也是系统设计的重要一环。在连接数据库时,要避免SQL注入攻击,可以通过预编译的PreparedStatement对象来执行SQL命令。对于用户输入的数据,需要进行验证和过滤,防止非法字符和异常值。 这个“餐馆点餐管理系统”项目涵盖了Java编程、数据库设计与管理、用户界面设计等多个方面,是一个很好的学习实践平台。通过这个项目,初学者不仅可以提升编程技能,还能对数据库管理和软件工程有更深入的理解。在实际开发过程中,还会遇到调试、测试、优化等挑战,这些都是成长为专业开发者不可或缺的经验积累
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值