51nod 1847 奇怪的数学题

2024-05-29 02:48
文章标签 51nod 奇怪 数学题 1847

本文主要是介绍51nod 1847 奇怪的数学题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Description

给出 N,K ,请计算下面这个式子:
∑Ni=1∑Nj=1sgcd(i,j)k
其中,sgcd(i, j)表示(i, j)的所有公约数中第二大的,特殊地,如果gcd(i, j) = 1, 那么sgcd(i, j) = 0。
考虑到答案太大,请输出答案对2^32取模的结果.
1≤N≤109,1≤K≤50
样例解释:
因为gcd(i, j)=1时sgcd(i,j)=0对答案没有贡献,所以我们只考虑gcd(i,j)>1的情况.
当i是2时,j是2时,sgcd(i,j)=1,它的K次方是1
当i是2时,j是4时,sgcd(i,j)=1,它的K次方是1
当i是3时,j是3时,sgcd(i,j)=1,它的K次方是1
当i是4时,j是2时,sgcd(i,j)=1,它的K次方是1
当i是4时,j是4时,sgcd(i,j)=2,它的K次方是8
当i是5时,j是5时,sgcd(i,j)=1,它的K次方是1

Input

两个数字N,K

Output

⼀⾏⼀个数表⽰答案。

Sample Input

5 3

Sample Output

13

Solution

min_25
是一个神奇的东西。

设f(d)表示d的第二大的约数,也就是d除以d的最小质因数。
显然答案可以表示为

ans=d=1nf(d)i=1nj=1n[gcd(i,j)=d] a n s = ∑ d = 1 n f ( d ) ∗ ∑ i = 1 n ∑ j = 1 n [ g c d ( i , j ) = d ]

将后面套路搞一搞可以得到
ans=d=1nf(d)2i=1nϕ(i)1 a n s = ∑ d = 1 n f ( d ) ∗ 2 ∑ i = 1 n ϕ ( i ) − 1

后面用杜教筛可以轻松解决,那么前面就用min_25解决就行了。

p[i]表示第i个质数
设g(n,i)表示 jjp[i]f[j]k ∑ j 是 质 数 或 j 的 最 小 质 因 子 不 小 于 p [ i ] f [ j ] k
设h(n,i)表示 jjp[i]jk ∑ j 是 质 数 或 j 的 最 小 质 因 子 不 小 于 p [ i ] j k
转移很套路,如下:
p[i]2>n p [ i ] 2 > n 时,显然 g(n,i)=g(n,i1)h(n,i)=h(n,i1) g ( n , i ) = g ( n , i − 1 ) , h ( n , i ) = h ( n , i − 1 )
否则
设sp[i]表示第一个到第i个质数的k次方和

g(n,i)=g(n,i+1)+p[i]e+1<=np[i](e1)k(h(np[i]e,i+1)sp[i])+p[i]ek g ( n , i ) = g ( n , i + 1 ) + ∑ p [ i ] e + 1 <= n p [ i ] ( e − 1 ) k ( h ( n p [ i ] e , i + 1 ) − s p [ i ] ) + p [ i ] e k

h(n,i)=h(n,i+1)+p[i]e+1<=np[i]ek(h(np[i]e,i+1)sp[i])+p[i](e+1)k h ( n , i ) = h ( n , i + 1 ) + ∑ p [ i ] e + 1 <= n p [ i ] e k ( h ( n p [ i ] e , i + 1 ) − s p [ i ] ) + p [ i ] ( e + 1 ) k

设p0表示 n n 以内质数的个数。
初始时g(n,p0+1)的值显然是n以内质数的个数,h(n,p0+1)的值显然是n以内质数的k次方的和,发现不知道怎么搞。

于是再弄一次min_25,将初始的g和h筛出来。
这次
设g(n,i)表示 jjp[i]1 ∑ j 是 质 数 或 j 的 最 小 质 因 子 不 小 于 p [ i ] 1
设h(n,i)表示 jjp[i]jk ∑ j 是 质 数 或 j 的 最 小 质 因 子 不 小 于 p [ i ] j k
转移如下

g(n,i)=g(n,i1)(g(np[i],i1)i+1) g ( n , i ) = g ( n , i − 1 ) − ( g ( n p [ i ] , i − 1 ) − i + 1 )

h(n,i)=h(n,i1)p[i]k(h(np[i],i1)sp[i1]) h ( n , i ) = h ( n , i − 1 ) − p [ i ] k ( h ( n p [ i ] , i − 1 ) − s p [ i − 1 ] )

初始值即g(n,0)和h(n,0)分别为n和自然数幂和。(自然数幂和要用第二类斯特林数)
转移完成后,得到的g和h就是上面第一个min_25筛的初始值。
总得来说,这题只需要两次min_25筛加一次杜教筛加一次自然数幂和还有最后的分块求答案就能做了。

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#define fo(i,a,b) for(ll i=a;i<=b;i++)
#define fd(i,a,b) for(ll i=a;i>=b;i--)
#define N 1010000
#define ll unsigned long long
using namespace std;
map<ll,ll> bphi;
ll ans,n,k,bz[N],p[N],phi[N],gn,g[N],h[N],g0,sp[N],ss[60][60],p0,m,num[N],d1[N],d2[N];
ll mi(ll a,ll b)
{
    ll c=1;
    for(;b;b/=2,a=a*a) if(b%2==1) c=c*a;
    return c;
}
ll gphi(ll n)
{
    if(n<N) return phi[n];
    if(bphi[n]>0) return bphi[n];
    ll ans;
    if(n%2==0) ans=n/2*(n+1);
    else ans=(n+1)/2*n;
    for(ll l=2,r;l<=n;l=r+1)
    {
        r=n/(n/l);
        ans=ans-(r-l+1)*gphi(n/l);
    }
    bphi[n]=ans;
    return ans;
}
ll getk(ll n)
{
    ll ans=0;
    fo(i,0,k)
    if(n>=i)
    {
        ll C=1;
        int flag=1;
        fo(j,n-i+1,n+1)
        {
            if(j%(i+1)==0&&flag) C=j/(i+1)*C,flag=0;
            else C=C*j;
        }
        ans=ans+ss[k][i]*C;
    }
    else break;
    return ans;
}
int main()
{
    scanf("%llu%llu",&n,&k);
    ss[0][0]=1;
    fo(i,1,k+1) fo(j,1,k+1) ss[i][j]=ss[i-1][j-1]+ss[i-1][j]*j;
    gn=(ll)sqrt(n);
    fo(i,2,N-1)
    {
        if(!bz[i])
        {
            p[++p[0]]=i,phi[i]=i-1;
            sp[p[0]]=sp[p[0]-1]+mi(i,k);
            if(i<=gn) p0=p[0];
        }
        fo(j,1,p[0])
        {
            ll k=i*p[j];
            if(k>=N) break;
            bz[k]=1;
            if(i%p[j]==0)
            {
                phi[k]=phi[i]*p[j];
                break;
            }
            phi[k]=phi[i]*phi[p[j]];
        }
    }
    phi[1]=1;
    fo(i,2,N-1) phi[i]+=phi[i-1];
    for(ll l=1,r;l<=n;l=r+1)
    {
        r=n/(n/l);
        if(n/l<=gn) d1[n/l]=++m;else d2[r]=++m;
        num[m]=n/l;
        g[m]=num[m]-1;h[m]=getk(num[m])-1;
    }
    fo(i,1,p0)
    {
        ll pk=mi(p[i],k);
        ll pf=1ll*p[i]*p[i];
        fo(j,1,m)
        if(pf<=num[j])
        {
            ll op=(num[j]/p[i])<=gn?d1[num[j]/p[i]]:d2[n/(num[j]/p[i])];
            g[j]=g[j]-(g[op]-i+1ll);
            h[j]=h[j]-pk*(h[op]-sp[i-1]);
        }
        else break;
    }
    fd(i,p0,1)
    {
        ll pk=mi(p[i],k);
        ll pf=1ll*p[i]*p[i];
        fo(j,1,m)
        if(pf<=num[j])
        {
            for(ll pmk=1,pm=p[i];pm*p[i]<=num[j];pmk=pmk*pk,pm=pm*p[i])
            {
                ll op=(num[j]/pm)<=gn?d1[num[j]/pm]:d2[n/(num[j]/pm)];
                g[j]=g[j]+pmk*pk+pmk*(h[op]-sp[i]);
                h[j]=h[j]+pmk*pk*pk+pmk*pk*(h[op]-sp[i]);
            }
        }
        else break;
    }
    for(ll l=1,r;l<=n;l=r+1)
    {
        r=n/(n/l);
        ll op1=(r<=gn)?d1[r]:d2[n/r];
        ll op2=(l-1)<=gn?d1[l-1]:d2[n/(l-1)];
        ll jy=gphi(n/l);
        jy=jy*2-1;
        ans=ans+(g[op1]-g[op2])*jy;
    }
    printf("%llu\n",ans&((1ll<<32)-1));
}

这篇关于51nod 1847 奇怪的数学题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1012434

相关文章

【51nod】算法马拉松4 F 移数字 【快速求N!%P】【FFT】

传送门:【51nod】算法马拉松4 F 移数字 涉及知识点:多项式求逆,多项式除法,多点插值,阶乘取模。 对于N!%P,复杂度为 O(N−−√log2N−−√) O(\sqrt N \log^2\sqrt N)。 但常数巨大,和暴力算实际复杂度只相差常数= = 这个是可以扩展到组合数取模的~ my  code: my~~code: #include <stdio.h>#includ

数学题--2860. 让所有学生保持开心的分组方法数

2860. 让所有学生保持开心的分组方法数 给你一个下标从 0 开始、长度为 n 的整数数组 nums ,其中 n 是班级中学生的总数。班主任希望能够在让所有学生保持开心的情况下选出一组学生: 如果能够满足下述两个条件之一,则认为第 i 位学生将会保持开心: 这位学生被选中,并且被选中的学生人数 严格大于 nums[i] 。这位学生没有被选中,并且被选中的学生人数 严格小于 nums[i]

CTF入门之奇怪的密码及图形编码总结篇(持续更新中ing)

CTF入门之奇怪的编码及图形编码(持续更新中ing UTF-8,unicode乱码社会主义核心价值观编码:在线解码: 与佛论禅:在线解密网站: 与熊论道:在线网站解密: 兽音:在线网站解密: 文本加密字母/汉字等等:文本加密为汉字 :文本加密为数字:文本加密为字母:文本加密为音乐符号:文本加密为国际音标:文本加密为盲文:文本加密为韩文:文本加密为日文:文本加密为花朵符号:文本加密为俄

最常用的SAT数学题解答方法分享

下面为大家总结的是一些最常见的SAT数学题的解答方法。SAT数学题的备考对于中国考生来说难度不是很大,但是如果能够掌握更多的方法,会让大家的答题效果更好,正确率也更高。下面我们来看看详细内容吧。   1. 代入法-----------最常见的方法,适用于所有数学题目,只要是答案中有确切的数目。   例题:If x and y are two different integers and t

奇怪的分式 蓝桥杯

Description 上小学的时候,小明经常自己发明新算法。一次,老师出的题目是:  1/4 乘以 8/5   小明居然把分子拼接在一起,分母拼接在一起,答案是:18/45 (参见图1.png) 老师刚想批评他,转念一想,这个答案凑巧也对啊,真是见鬼! 对于分子、分母都是 1~9 中的一位数的情况,还有哪些算式可以这样计算呢? 请写出所有不同算式的个数(包括题中举例的)。 显然,

连号区间数 小明这些天一直在思考这样一个奇怪而有趣的问题:

package org.bluebridge.topics;/** 连号区间数小明这些天一直在思考这样一个奇怪而有趣的问题:在1~N的某个全排列中有多少个连号区间呢?这里所说的连号区间的定义是:如果区间[L, R] 里的所有元素(即此排列的第L个到第R个元素)递增排序后能得到一个长度为R-L+1的“连续”数列,则称这个区间连号区间。当N很小的时候,小明可以很快地算出答案,但是当N变大的时候,问题就

HDU 1847 Good Luck in CET-4 Everybody! 博弈

题意就不解释了 说一下思路: 首先任何2的幂可以组成任何数。 比如n==9; 先手不管拿k个后手可以拿3*m-k个;这样只要是3的倍数有余数先手一定会赢。 后手赢得方法类似。 个人认为这种只有一堆的题目一般都是和巴什博弈联系,实在不会自己可以举几个例子看看。。 Description 大学英语四级考试就要来临了,你是不是在紧张的复习?也许紧张得连短学期的A

POJ 1847 Tram(Dijkstra单源有向图最短路径算法)

//Accepted 212 KB 0 ms C++ 1096 B 2013-02-27 19:42:55/*Sample Input3 2 12 2 32 3 12 1 2Sample Output0题意:给出N个站点,每个站点都有铁路通向其它的多个站点。如果当前要走的铁路是现在开关指向的铁路,则直接走即可,否则要手动扳动开关。 难理解的可能是题意:直接指向的 w = 0, 需要

【数学题-递推找规律】BNU 4225 杨辉三角形

【题目链接】click here~~ 【题目大意】 LZM 同学比较牛, Lsy 最近也越来越生猛,他们思路快,代码速度神勇。近期惊闻此二人均要参加校赛,队里决定出些题目卡他们,因为他们的罢工给题目组留下了繁重的负担……(报复报复) 于是, XsugarX 瞄准了 LZM 不太喜欢看的数学题目以及 Lsy 猜公式的喜好,奸笑中( ^.^ )。这个数学问题是个比较古老的问题,有如下

【求助帖】用PyTorch搭建MLP网络时遇到奇怪的问题

求助:我在测试自己搭建的通用MLP网络时,发现它与等价的参数写死的MLP网络相比效果奇差无比,不知道是哪里出了问题,请大佬们帮忙看下。 我写的通用MLP网络: class MLP(nn.Module):def __init__(self, feature_num, class_num, *hidden_nums):super().__init__()self.feature_num = fea