zoukankan      html  css  js  c++  java
  • LOJ#6053. 简单的函数

    II.LOJ#6053. 简单的函数

    重申一下min25筛应用的条件:

    • 是积性函数。
    • 质数处取值是低阶多项式。
    • 质数次幂处取值可以快速求出。

    满足以上三点的任意函数均可以min25筛。

    现在看到这题。乍一看 \(p\operatorname{xor}a\) 这种东西看上去一脸非多项式的样子;但是因为我们只关心质数处取值是否是多项式,因为除了 \(2\) 以外的质数均为奇,且质数处的 \(a\) 必为 \(1\),则除了 \(f(2)=3\) 以外,其余的 \(f(p)=p-1\),是低阶多项式。故我们只需特判掉 \(n\geq 2\) 时手动给筛出来的结果加上 \(2\) 即可。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int mod=1e9+7;
    typedef long long ll;
    ll n;
    int m,pri[1001000],sp[2][1001000],g[2][1001000];
    void sieve(){
    	for(int i=2;i<=m;i++){
    		if(!pri[i])pri[++pri[0]]=i,sp[0][pri[0]]=sp[0][pri[0]-1]+1,sp[1][pri[0]]=(sp[1][pri[0]-1]+i)%mod;
    		for(int j=1;j<=pri[0]&&i*pri[j]<=m;j++){
    			pri[i*pri[j]]=true;
    			if(!(i%pri[j]))break;
    		}
    	}
    }
    ll kth[1001000];
    int sml[1001000],lar[1001000],tot;
    int H(ll x,int y){
    	if(pri[y]>=x)return 0;
    	int X=(x<=m?sml[x]:lar[n/x]);
    	int ret=(2ll*mod+g[1][X]-g[0][X]-(sp[1][y]-sp[0][y]))%mod;
    	for(int i=y+1;i<=pri[0]&&1ll*pri[i]*pri[i]<=x;i++){
    		ll pa=pri[i];
    		for(int a=1;pa<=x;a++,pa*=pri[i])(ret+=1ll*(pri[i]^a)*(H(x/pa,i)+(a!=1))%mod)%=mod;
    	}
    	return ret;
    }
    int main(){
    	scanf("%lld",&n),m=sqrt(n),sieve();
    //	for(int i=1;i<=pri[0];i++)printf("%d ",pri[i]);puts("");
    //	for(int i=1;i<=pri[0];i++)printf("%d ",sp[0][i]);puts("");
    //	for(int i=1;i<=pri[0];i++)printf("%d ",sp[1][i]);puts("");
    	for(ll i=1;i<=n;i=n/(n/i)+1){
    		kth[++tot]=n/i;
    		int I=kth[tot]%mod;
    		g[0][tot]=(I+mod-1)%mod,g[1][tot]=(1ll*I*(I+1)/2+mod-1)%mod;
    		if(kth[tot]<=m)sml[kth[tot]]=tot;else lar[n/kth[tot]]=tot;
    	}
    //	for(int i=1;i<=tot;i++)printf("%d ",kth[i]);puts("");
    	for(int i=1;i<=pri[0];i++)for(int j=1;j<=tot&&1ll*pri[i]*pri[i]<=kth[j];j++){
    		ll nexi=kth[j]/pri[i];int I=(nexi<=m?sml[nexi]:lar[n/nexi]);
    		(g[0][j]+=(mod-g[0][I]+sp[0][i-1])%mod)%=mod;
    		(g[1][j]+=mod-1ll*pri[i]*(g[1][I]-sp[1][i-1]+mod)%mod)%=mod;
    	}
    	printf("%d\n",H(n,0)+1+2*(n>=2));
    	return 0;
    } 
    

  • 相关阅读:
    hdu4911 简单树状数组
    hdu4911 简单树状数组
    hdu4912 LCA+贪心
    hdu4912 LCA+贪心
    hdu4907 水dp 或者set
    hdu4907 水dp 或者set
    hdu4908 中位数子串
    hdu4908 中位数子串
    hdu4909 状态压缩(偶数字符子串)
    hdu4909 状态压缩(偶数字符子串)
  • 原文地址:https://www.cnblogs.com/Troverld/p/14619885.html
Copyright © 2011-2022 走看看