zoukankan      html  css  js  c++  java
  • 密码解锁

    密码解锁

    给出一个数列({a_i}),限定上界n,对于任意一个位置i,i的Mobius函数值,等于i的倍数的位置上的值,t组询问,给出m,求第m个位置上的值。

    不难看出为数论问题,现在关键在于建模,于是不不难有

    [a_m+a_{2m}+...+a_{[n/m]m}=mu(m) ]

    [mu(m)=sum_{m|d}^na_d ]

    由Mobius反演定理,我们有

    [a_m=sum_{m|d}^nmu(d)mu(d/m)=sum_{d=1}^{[n/d]}mu(dm)mu(d)=sum_{d=1}^{[n/d]}mu^2(d)mu(m)(gcd(d,m)==1) ]

    (sum_{i=1}^nmu^2(i))联想容斥原理,采取更改容斥范围的办法解决问题,设(N=[n/m]),于是有

    [a_m=sum_{d=1}^{sqrt{N}}mu(d)sum_{d^2|e}^N(gcd(e,m)==1)= ]

    [sum_{d=1}^{sqrt{N}}mu(d)sum_{e=1}^{[N/d^2]}(gcd(ed^2,m)==1) ]

    因为(d^2)的存在不好反演,考虑提出特判

    [a_m=sum_{d=1}^{sqrt{N}}mu(d)(gcd(d,m)==1)sum_{e=1}^{[N/d^2]}(gcd(e,m)==1)= ]

    [sum_{d=1}^{sqrt{N}}mu(d)(gcd(d,m)==1)sum_{e=1}^{[N/d^2]}sum_{x|e,x|m}mu(x)= ]

    [sum_{d=1}^{sqrt{N}}mu(d)(gcd(d,m)==1)sum_{x|m}mu(x)[frac{N}{d^2e}] ]

    容易知道m的约数个数是固定的,于是考虑单独处理出其(mu)值,接下直接枚举式子,不难得知时间复杂度应为(O(sqrt{N}log_2^N+sqrt{N}sigma(m))=O(sqrt{N}sigma(m)))

    参考代码:

    #include <iostream>
    #include <cstdio>
    #define il inline
    #define ri register
    #define ll long long
    #define swap(x,y) x^=y^=x^=y
    using namespace std;
    bool check[50001];
    int prime[10000],pt,mu[50001],
        ys[2000],ym[2000],yt;
    il int Mu(ll);
    template<class free>
    il void read(free&);
    il void prepare(int);
    il ll gcd(ll,ll);
    int main(){
        int lsy;read(lsy),prepare(50000);
        ll n,m,i,j,ans1,ans2;
        while(lsy--){
            read(n),read(m);
            n/=m,yt&=0,ans1&=0;
            for(i=1;i*i<m;++i)
                if(!(m%i))
                    ys[++yt]=i,ym[yt]=Mu(i),
                        ys[++yt]=m/i,ym[yt]=Mu(m/i);
            if(i*i==m)ys[++yt]=i,ym[yt]=Mu(i);
            for(i=1;i*i<=n;++i){
                ans2&=0;
                if(gcd(i,m)==1)
                    for(j=1;j<=yt;++j)
                        ans2+=ym[j]*(n/(i*i)/ys[j]);
                ans1+=ans2*mu[i];
            }printf("%lld
    ",ans1*Mu(m));
        }
        return 0;
    }
    il ll gcd(ll a,ll b){
        while(b)swap(a,b),b%=a;return a;
    }
    il int Mu(ll n){
        ll i;int tot(0);
        for(i=2;i*i<=n;++i)
            if(!(n%i)){
                n/=i;if(!(n%i))return 0;
                ++tot;
            }if(n>1)++tot;
        return (tot&1)?-1:1;
    }
    il void prepare(int n){
        ri int i,j;mu[1]=1;
        for(i=2;i<=n;++i){
            if(!check[i])prime[++pt]=i,mu[i]=-1;
            for(j=1;j<=pt&&prime[j]*i<=n;++j){
                check[i*prime[j]]|=true;
                if(!(i%prime[j]))break;
                mu[i*prime[j]]=~mu[i]+1;
            }
        }
    }
    template<class free>
    il void read(free &x){
        x&=0;ri char c;while(c=getchar(),c<'0'||c>'9');
        while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
    }
    
    
  • 相关阅读:
    JS浮点数的加减乘除运算
    鼓励心里的阳光
    mysql创建新用户并分配数据库权限
    CentOS下的Memcache安装步骤(Linux+Nginx+PHP+Memcached)
    Python发送邮件
    SQL操作语句
    Mysql数据库操作语句
    Cookie,Session的区别
    Jmeter性能测试-分布式压力测试
    性能测试指标
  • 原文地址:https://www.cnblogs.com/a1b3c7d9/p/10884652.html
Copyright © 2011-2022 走看看