• 【spoj】DIVCNTK


    Portal -->Spoj DIVCNTK

    Solution

      这题的话其实是。。洲阁筛模板题?差不多吧

      题意就是给你一个函数(S_k(x))

    [S_k(n)=sumlimits_{i=1}^{n} sigma_0(i^k) ]

      其中(sigma_0(x))表示的是(x)的约数个数,现在已知(n)(k)(S_k(n)) mod (2^{64})
      

      额首先(sigma_0(x))是个积性函数

      然后我们会发现。。这个东西在素数处的取值还是很好求的

    [egin{aligned} &sigma_0(p)=2\ &sigma_0(p^k)=k+1\ &sigma_0((p^k)^q)=qk+1\ end{aligned} ]

      那然后用(g_i)表示([1,n])的素数个数,(h_{i,j})表示(sumlimits_{k=2}^{i}[k的最小质因子>=P_j]sigma_0(k))

      然后用洲阁筛(或者额。。min_25)的那种方法来搞一下就好了,具体的讲解的话传送一波好了qwq

      Portal -->洲阁筛&min_25筛

      具体的一些实现细节都在上面那篇讲解向博文里面了不想再打一遍了qwq

    ​   

      代码大概长这个样子(然而我写的貌似是min_25。。。)以及这题貌似卡常有点qwq

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define ll long long
    #define ull unsigned long long
    using namespace std;
    const int MAXN=1e5+10;
    ll g[MAXN*2],loc1[MAXN*2],loc2[MAXN*2],rec[MAXN*2];
    int P[MAXN];
    bool vis[MAXN];
    ll n,m,K,cnt,Up,cntval,sq,T;
    ull ans;
    void prework(int n);
    void init_loc();
    int Pos(ll x){return x<=sq?loc1[x]:loc2[n/x];}
    void get_g();
    ull H(ll i,int j);
    
    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%lld",&n,&K);
    		sq=sqrt(n)+0.5;
    		init_loc();
    		get_g();
    		ans=H(n,1)+1;
    		printf("%llu
    ",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[P[j]*i]=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) g[i]=rec[i]-1;
    	for (int j=1;j<=cnt&&1LL*P[j]*P[j]<=n;++j)//P的取值范围都是<sqrt(n)
    		for (int i=cntval;i>=1&&rec[i]>=1LL*P[j]*P[j];--i)
    			g[i]-=g[Pos(rec[i]/P[j])]-g[Pos(P[j]-1)];
    }
    
    ull H(ll i,int j){
    	if (i<=1) return 0;
    	ull ret=0;
    	ll tmp;
    	int k;
    	for (k=j;k<=cnt&&1LL*P[k]*P[k]<=n&&1LL*P[k]*P[k]<=i;++k){
    		tmp=P[k];
    		for (int q=1;tmp<=i;tmp*=P[k],++q)
    			ret+=(H(i/tmp,k+1)+1)*(q*K+1);
    	}
    	if (i>=P[k-1])//将i<P^2(也就是全是素数处点值的)部分算进去
    		ret+=(ull)(K+1)*(g[Pos(i)]-g[Pos(P[k-1])]);
    	return ret;
    }
    
  • 相关阅读:
    解决: 误将分区的GHO镜像文件恢复到整个硬盘
    腾讯的迷你门户首页新闻用到的Silverlight技术引用
    [转]如何在word文档里面的小方框内打钩
    Microsoft .NET Framework 3.5/4 Client Profile
    Java Web 开发软件下载地址
    tomcat 6.0环境, 网页超链接,文件下载另存为时,不能识别msi文件类型,另存为只能选htm和所有文件。
    英语小记
    去掉WORD文档中向下的小箭头(换行符)
    开个小餐馆要多少成本
    如何租间餐饮店
  • 原文地址:https://www.cnblogs.com/yoyoball/p/9193570.html
Copyright © 2020-2023  润新知