• 【51nod1847】奇怪的数学题(Min_25筛+杜教筛)


    题面

    传送门

    题解

    这题有毒……不知为啥的错误调了半天……

    (f(i)={sgcd(i)}),那么容易看出(f(i))就是(i)的次大质因子,用(i)除以它的最小质因子即可计算

    于是题目所求即为

    [sum_{i=1}^nsum_{j=1}^n{f(gcd(i,j))}^k ]

    [sum_{d=1}^n {f(d)}^ksum_{i=1}^{leftlfloorfrac{n}{d} ight floor}sum_{j=1}^{leftlfloorfrac{n}{d} ight floor}[gcd(i,j)=1] ]

    [sum_{d=1}^n {f(d)}^k(2sum_{i=1}^{leftlfloorfrac{n}{d} ight floor}varphi(i)-1) ]

    后面那个根据(varphi)的定义就可以推出来

    因为后面括号中的式子只与({leftlfloorfrac{n}{d} ight floor})的值有关,我们可以考虑整除分块,那么括号里的东西就是一个杜教筛

    那么我们现在的问题就是对于前半部分怎么快速求和了。我们考虑(Min\_25)筛的过程,其中(g(n,j))表示所有(1)(n)中的质数或最小质因子大于(P_j)的所有数的(k)次方之和,即

    [g(n,j)=sum_{i=1}^ni^k[iin P or min_p(i)>P_j] ]

    中间的转移中有这么一步

    [g(n,i)=g(n,j-1)-{P_j}^k(g({leftlfloorfrac{n}{P_j} ight floor},j-1)-sum_{i=1}^{j-1}{P_i}^k) ]

    考虑后面减去的东西,是所有最小质因子等于(P_j)且自身为合数的数的(k)次方之和,即

    [sum_xx^k[x otin P and min_p(x)=P_j] ]

    然后我们惊喜地发现,后面减去的东西中,括号里的东西就是上面所有满足条件的(x)({f(x)}^k)之和!

    那么我们就可以直接(Min\_25)筛来计算({f(x)}^k)的前缀和了,那么一段区间只要差分一下就可以了

    最后有个尴尬的问题,就是这个模数不是质数,所以我们在初始化的时候需要快速计算(sum_{i=1}^n i^k)就不能拉格朗日插值了

    那么只好用第二类斯特林数优化了

    [egin{aligned} sumlimits_{i=1}^{n}i^K&=sum_{i=1}^nsum_{j=1}^Kegin{Bmatrix}K\jend{Bmatrix}i^underline{j}\ &=sum_{j=1}^Kegin{Bmatrix}K\jend{Bmatrix}sum_{i=1}^ni^underline{j}\ &=sum_{j=1}^Kegin{Bmatrix}K\jend{Bmatrix}frac{{(n+1)}^underline{j+1}}{j+1} end{aligned}]

    然后没有然后了

    //minamoto
    #include<bits/stdc++.h>
    #define R register
    #define int unsigned int
    #define IT map<int,int>::iterator
    #define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
    #define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    using namespace std;
    const int N=1e5+5;
    int w[N<<1],g[N<<1],h[N<<1],G[N<<1],id1[N],id2[N],p[N],pw[N],sp[N],phi[N],S[55][55];
    map<int,int>mp;bitset<N>vis;int n,m,k,tot,sqr,id,ans,now,las;
    int ksm(R int x,R int y){
    	R int res=1;
    	for(;y;y>>=1,x*=x)if(y&1)res*=x;
    	return res;
    }
    void init(int n){
    	phi[1]=1;
    	fp(i,2,n){
    		if(!vis[i])p[++tot]=i,pw[tot]=ksm(i,k),sp[tot]=sp[tot-1]+pw[tot],phi[i]=i-1;
    		for(R int j=1;j<=tot&&1ll*i*p[j]<=n;++j){
    			vis[i*p[j]]=1;
    			if(i%p[j]==0){phi[i*p[j]]=phi[i]*p[j];break;}
    			phi[i*p[j]]=phi[i]*(p[j]-1);
    		}
    	}
    	fp(i,1,n)phi[i]+=phi[i-1];
    	S[0][0]=1;
    	fp(i,1,k){
    		S[i][1]=1;
    		fp(j,2,i)S[i][j]=S[i-1][j]*j+S[i-1][j-1];
    	}
    }
    int Phi(int n){
    	if(n<=sqr)return phi[n];
    	IT it=mp.find(n);
    	if(it!=mp.end())return it->second;
    	int res=n*(n+1)>>1;
    	for(R int i=2,j;i<=n;i=j+1)
    		j=n/(n/i),res-=Phi(n/i)*(j-i+1);
    	return mp[n]=res;
    }
    int calc(int n){
    	int res=0,tmp;
    	fp(i,1,min(k,n)){
    		tmp=S[k][i];
    		fp(j,n-i+1,n+1)(j%(i+1)==0)?tmp*=j/(i+1):tmp*=j;
    		res+=tmp;
    	}return res;
    }
    signed main(){
    //	freopen("testdata.in","r",stdin);
    	scanf("%u%u",&n,&k),init(sqr=sqrt(n));
    	for(R int i=1,j;i<=n;i=j+1){
    		j=n/(n/i),w[++m]=n/i;
    		w[m]<=sqr?id1[w[m]]=m:id2[n/w[m]]=m;
    		g[m]=calc(w[m])-1,h[m]=w[m]-1;
    	}
    	fp(j,1,tot)for(R int i=1;1ll*p[j]*p[j]<=w[i];++i){
    		id=(w[i]/p[j]<=sqr)?id1[w[i]/p[j]]:id2[n/(w[i]/p[j])];
    		g[i]-=pw[j]*(g[id]-sp[j-1]);
    		h[i]-=h[id]-j+1;
    		G[i]+=g[id]-sp[j-1];
    	}
    	for(R int i=2,j;i<=n;i=j+1){
    		j=n/(n/i),id=(j<=sqr)?id1[j]:id2[n/j];
    		now=G[id]+h[id],ans+=((Phi(n/i)<<1)-1)*(now-las),las=now;
    	}
    	printf("%u
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    .NET 高效开发之不可错过的实用工具(第一的当然是ReSharper插件)
    灵活运用 SQL SERVER FOR XML PATH 转
    Python 3.X 要使用urllib.request 来抓取网络资源。转
    22-1 拖拽与烟花案例
    21、bootstrap框架
    20、promise与ajax jsonp
    18、MySQL
    19、AJAX
    17、php
    16-1 ECMA5与ECMA6的函数定义
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10420143.html
Copyright © 2020-2023  润新知