zoukankan      html  css  js  c++  java
  • min_25筛学习笔记

    min25筛是一个神奇的筛法

    是较为常用的筛法

    假设要求(f(x))
    要求

    1. (f)是积性函数
    2. (f(p^e))是关于(p)的低阶多项式
    3. 存在一个在质数处取值与f一样的完全积性函数

    以下以洛谷上的板子题为例
    求的积性函数是(f(p^e)=p^e(p^e-1)=(p^e)^2-p^e)

    主要思路是分情况讨论,按照实数和合数进行分类

    问题变成了求

    [sumlimits_{pleq n}f(p)+sumlimits_{i=1}^n[i otin prime]f(i) ]

    对后面那个再次进行分类讨论,枚举最小质因子及其指数

    因为最小质因子是根号级别的所以可以直接枚举

    [sumlimits_{pleq n}f(p)+sumlimits_{pin prime && p^eleq n}f(p^e)(sumlimits_{ileq frac{n}{p^e} && mindiv(i)>p}f(i)) ]

    分完情况了我们来进行计算

    因为(f(p))是低阶多项式,所以可以拆成单项式,计算(f(p)=p^k)的前缀和

    这里就是拆成一次和二次

    质数部分

    因为

    首先肯定是不能进行线性筛的

    我们来整一个DP

    (g(n,i)=sumlimits_{j=1}^n[jleq n && mindiv(j)>prime_j]j^k)

    (sp_i=sumlimits_{i=1}^nf(p_i))

    用人话说就是所有小于(n)的数中没有小于第(i)个质数的质因子的数

    后面的(i^k)是一个和(f)在质数处取值一样的完全积性函数

    我们发现(g(n,x))就是最后的答案
    其中(p_x)是最后一个小于等于(sqrt{n})的质数

    考虑怎样递推

    [g(n,i)=g(n,i-1)-p_i^k(g(lfloorfrac{n}{p_i} floor,j-1)-g(p_{i-1},i-1)) ]

    [g(n,i)=g(n,i-1)-p_i^k(g(lfloorfrac{n}{p_i} floor,j-1)-sp_{i-1}) ]

    考虑这个递推式的含义

    (i-1)(i)少了一些数
    因为是完全积性函数,所以可以直接把最小质因子提出来

    后面那个是为了防止把质数给弄没了

    因为我们需要的(p)是根号级别的,所以可以直接线性筛暴力算

    但是(n)的范围还是太大了,无法都算出来

    但我们有结论

    [lfloorfrac{lfloorfrac{n}{a} floor}{b} floor=lfloorfrac{n}{ab} floor ]

    所以我们的(n)在转移的过程中一直除来除去,也只会用到能表示成(lfloorfrac{n}{x} floor)的值

    这显然只有(sqrt{n})

    我们需要在存储dp数组的时候进行一些奥妙重重的实现

    发现第二维每次只会增加1,所以可以直接滚掉

    计算答案

    同样使用dp来计算答案

    (S(n,i))表示最小质因子大于(p_i)的数的函数值之和

    那么最终要求得就是(S(n,0))

    这里的(g(n))(g(n,x))(x)是小于等于(sqrt{n})的最大值

    [S(n,i)=g(n)-sp_i+sumlimits_{p_k^eleq n&& k>i)}f(p_k^e)(S(lfloorfrac{n}{p_k^e} floor,k)+[e ot=1]) ]

    后面那个中括号的意思差不多是那个数不是质数

    然后就做完了

    直接爆搜就可以,复杂度是对的

    不能处理多组询问

    洛谷板子

    #include<cstdio>
    #include<cmath>
    using namespace std;
    namespace Patchouli{
      const int N=10000005;
      const int MOD=1000000007;
      const int INV2=500000004;
      const int INV3=333333336;
      long long prime[N],mindiv[N],sp1[N],sp2[N],cnt;
      long long n;
      long long sqr,tot,g1[N],g2[N],w[N],pos1[N],pos2[N];
      inline long long read(){
        long long a=1,b=0;char t;
        do{t=getchar();if(t=='-')a=-1;}while(t>'9'||t<'0');
        do{b=b*10-'0'+t;t=getchar();}while(t>='0'&&t<='9');
        return a*b;
      }
      inline void init(int n){
        mindiv[1]=1;
        for(int i=2;i<=n;++i){
          if(!mindiv[i]){
    	mindiv[i]=i;
    	prime[++cnt]=i;
    	sp1[cnt]=(sp1[cnt-1]+i)%MOD;
    	sp2[cnt]=(sp2[cnt-1]+1ll*i*i)%MOD;
          }
          for(int j=1;j<=cnt&&i*prime[j]<=n&&prime[j]<=mindiv[i];++j)
    	mindiv[i*prime[j]]=prime[j];
        }
      }
      long long S(long long x,int y){
        if(prime[y]>=x)return 0;
        long long k=x<=sqr?pos1[x]:pos2[n/x];
        long long ans=(g2[k]-g1[k]+MOD-(sp2[y]-sp1[y])+MOD)%MOD;
        for(int i=y+1;i<=cnt&&prime[i]*prime[i]<=x;++i){
          long long tmp=prime[i];
          for(int e=1;tmp<=x;++e,tmp=tmp*prime[i]){
    	long long res=tmp%MOD;
    	ans=(ans+res*(res-1)%MOD*(S(x/tmp,i)+(e!=1)))%MOD;
          }
        }
        return ans%MOD;
      }
      int QAQ(){
        n=read();
        sqr=sqrt(n);
        init(sqr);
        for(long long l=1,r;l<=n;l=r+1){
          r=n/(n/l);
          w[++tot]=n/l;
          long long tmp=(n/l)%MOD;
          //求出从2到tmp的自然数之和
          g1[tot]=(tmp*(tmp+1)/2)%MOD-1;
          //求出从2到tmp的平方和,式子写这么奇怪只是为了少取模  
          g2[tot]=tmp*(tmp+1)/2%MOD*(2*tmp+1)%MOD*INV3%MOD-1;
          //记录一下各个值出现的位置
          if(n/l<=sqr)pos1[n/l]=tot;
          else pos2[n/(n/l)]=tot;
        }
        for(int i=1;i<=cnt;++i){
          for(int j=1;j<=tot&&prime[i]*prime[i]<=w[j];++j){
    	long long k=w[j]/prime[i];
    	k=k<=sqr?pos1[k]:pos2[n/k];
    	g1[j]-=prime[i]*(g1[k]-sp1[i-1]+MOD)%MOD;
    	g2[j]-=prime[i]*prime[i]%MOD*(g2[k]-sp2[i-1]+MOD)%MOD;
    	g1[j]%=MOD;
    	g2[j]%=MOD;
          }
        }
        printf("%lld
    ",(S(n,0)+1+MOD)%MOD);
        return false;
      }
    }
    int main(){
      return Patchouli::QAQ();
    }
    
  • 相关阅读:
    希腊字母写法
    The ASP.NET MVC request processing line
    lambda aggregation
    UVA 10763 Foreign Exchange
    UVA 10624 Super Number
    UVA 10041 Vito's Family
    UVA 10340 All in All
    UVA 10026 Shoemaker's Problem
    HDU 3683 Gomoku
    UVA 11210 Chinese Mahjong
  • 原文地址:https://www.cnblogs.com/oiertkj/p/12321961.html
Copyright © 2011-2022 走看看