• LOJ2085. 「NOI2016」循环之美


    定义一个(frac{x}{y})是“纯循环小数”,当且仅当:化成小数之后,可以写成(a.dot{c_1}c_2c_3c_4dotsdot{c_p})的形式。

    (xin[1,n])(yin[1,m]),有多少对((x,y),x perp y)满足(frac{x}{y})(k)进制下是纯循环小数。

    (n,mle 10^9,kle 2000)


    分析条件:如果是,当且仅当(exist p>0,xequiv k^pxpmod y)。也就是(kperp y)

    所以题目也就是要求(sum_{i=1}^msum_{j=1}^n [iperp j][iperp k])

    考虑拆式子。

    说在前面:作为数论白痴,下面估的时间复杂度往往是不准确的。如果有大佬路过希望指教一下。

    当拆([i perp j])

    经过推导得(sum_d [dperp k]mu(d)lfloorfrac{n}{d} floorsum_{i=1}^{lfloorfrac{m}{d} floor}[iperp k])

    (f(n)=sum_{i=1}^n[iperp k]=lfloorfrac{n}{k} floorphi(k)+f(nmod k))。可以快速求,不是复杂度瓶颈。

    对于(sum_d [dperp k]mu(d)lfloorfrac{n}{d} floor f(lfloorfrac{m}{d} floor))整除分块,现在要求前缀和,即(g(n,k)=sum_{d=1}^n mu(d)[dperp k])

    一种推法

    ([dperp k])拆开推一波式子可以得到(g(n,k)=sum_{t|k}mu(t)sum_{d=1}^{lfloorfrac{n}{t} floor}mu(dt)=sum_{t|k}mu(t)^2sum_{d=1}^{lfloorfrac{n}{t} floor}mu(d)[dperp t]=sum_{t|k}mu(t)^2g(lfloorfrac{n}{t} floor,t))。整除分块搞下去。

    边界是(g(n,1))(g(0,k))。其中(g(n,1))可以杜教筛求。

    时间复杂度(记忆化):(O(n^{2/3}+(k的因子个数)sqrt n))

    另一种推法

    (p)(k)的一个质因数,则(k)可以表示成(p^tq)的形式。

    (g(n,k)=sum_{i=1}^n[iperp q]mu(i)-sum_{p|i}[iperp q]mu(i)=g(n,q)+g(lfloorfrac{n}{p^t} floor,k))

    边界同上,时间复杂度(记忆化):(O(n^{2/3}+(k的质因子个数)sqrt n))

    当拆([iperp k])

    (f(m,n,k)=sum_{i=1}^msum_{j=1}^n [iperp j][iperp k])

    经过推导得(f(m,n,k)=sum_{d|k}mu(d)f(n,lfloorfrac{m}{d} floor,d))

    边界条件(k=1),化一下得(sum_d mu(d)lfloorfrac{n}{d} floorlfloorfrac{m}{d} floor)。整除分块,杜教筛算(mu)的前缀和。

    这个东西不太会分析,但是实践表明递归的次数不是很多(没有对(f)进行记忆化的情况下)。杜教筛记忆化(lfloorfrac{n}{d} floor)(lfloorfrac{m}{d} floor)这样的前缀和,总时间(O(n^{2/3}+m^{2/3}))。整除分块的时间复杂度大概是(O(sqrt{max(n,m)})。总的时间复杂度不会算……

    代码是最后一种做法。


    using namespace std;
    #include <bits/stdc++.h>
    #define ll long long
    //#define ll __int128
    #define N 6000005
    int gcd(int a,int b){
    	int k;
    	while (b)
    		k=a%b,a=b,b=k;
    	return a;
    }
    int n,m,k;
    int p[N],np;
    bool inp[N];
    int mu[N],mnp[N];
    int smu[N];
    void init(int n=6000000){
    	mu[1]=1;
    	for (int i=2;i<=n;++i){
    		if (!inp[i])
    			p[++np]=i,mnp[i]=i,mu[i]=-1;
    		for (int j=1;j<=np && i*p[j]<=n;++j){
    			inp[i*p[j]]=1;
    			mnp[i*p[j]]=p[j];
    			if (i%p[j]==0)
    				break;
    			mu[i*p[j]]=-mu[i];
    		}
    	}
    	for (int i=1;i<=n;++i)
    		smu[i]=smu[i-1]+mu[i];
    }
    const int EMP=-1926081700;
    struct memory{
    	int n;
    	ll v0[N],v1[N];
    	void init(int _n){
    		n=_n;
    		for (int i=1;i*i<=n;++i)
    			v0[i]=v1[i]=EMP;
    	}
    	ll &operator[](int x){return (ll)x*x<=n?v0[x]:v1[n/x];}
    } bzn,bzm;
    ll S1(int n,memory &bzn){
    	if (n<=6000000)
    		return smu[n];
    	if (bzn[n]!=EMP)
    		return bzn[n];
    	ll sum=0;
    	for (int i=2;i<=n;){
    		int d=n/i,j=n/d;
    		sum+=(ll)(j-i+1)*S1(d,bzn);
    		i=j+1;
    	}
    	return bzn[n]=1-sum;
    }
    ll S2(int m,int n,int rev){
    	if (rev)
    		swap(m,n);
    	ll sum=0,pre=0;
    	for (int i=1;i<=m && i<=n;){
    		int dn=n/i,dm=m/i,j=min(n/dn,m/dm);
    		ll tmp=S1(j,n/dn<m/dm?bzn:bzm);
    		sum+=(ll)(tmp-pre)*dn*dm;
    		pre=tmp;
    		i=j+1;
    	}
    	return sum;
    }
    ll f(int m,int n,int k,int rev){
    	if (m==0 || n==0)
    		return 0;
    	ll s=0;
    	if (k==1){
    		s+=S2(m,n,rev);
    		return s;
    	}
    	int i=1;
    	for (;i*i<k;++i)
    		if (k%i==0){
    			if (mu[i]) 
    				s+=mu[i]*f(n,m/i,i,rev^1);
    			if (mu[k/i]) 
    				s+=mu[k/i]*f(n,m/(k/i),k/i,rev^1);
    		}
    	if (i*i==k && mu[i])
    		s+=mu[i]*f(n,m/i,i,rev^1);
    	return s;
    }
    int main(){
    	freopen("in.txt","r",stdin);
    //	freopen("out.txt","w",stdout);
    	init();
    	scanf("%d%d%d",&n,&m,&k);
    	bzn.init(n);
    	bzm.init(m);
    	printf("%lld
    ",(long long)f(m,n,k,0));
    //	printf("%lld
    ",cnt);
    	return 0;
    }
    
  • 相关阅读:
    关于AutoResetEvent和ManualResetEvent
    (转)使用 ODP.NET 和引用游标优化结果集
    胰腺
    SQL Cache Dependency
    败犬的远吠?
    吃亏和付出经常是必须的(转)
    AutoResetEvent 与 ManualResetEvent送花例子
    linux yum install
    SpringMVC+JPA+SpringData配置
    Spring AOP 实现原理
  • 原文地址:https://www.cnblogs.com/jz-597/p/14310609.html
Copyright © 2020-2023  润新知