zoukankan      html  css  js  c++  java
  • 题解「Luogu1587 [NOI2016]循环之美」

    题意

    求满足 (1 leq x leq n,1 leq y leq m) 的在 (k) 进制下能写成纯循环小数的最简分数 (frac{x}{y}) 的个数。

    题解


    证明:

    [ ext{Ans}=sum_{x=1}^{n}sum_{y=1}^{m}[x ot y][y ot k] ]

    首先要知道, (k) 进制下 (frac{x}{y}) 小数点右移一位等于 (frac{x}{y} imes k)

    假设 (frac{x}{y}) 小数部分的循环节长度为 (l) ,由于纯循环小数的特殊性质有:

    [[frac{xk^l}{y}]=[frac{x}{y}] ]

    这里的方括号代表取小数部分。

    那么有:

    [frac{xk^l}{y}-lfloorfrac{xk^l}{y} floor=frac{x}{y}-lfloorfrac{x}{y} floor ]

    注意这里是下取整。

    两边同时乘上 (y)

    [xk^l-lfloorfrac{xk^l}{y} floor imes y=x-lfloorfrac{x}{y} floor imes y ]

    变化成同余式:

    [xk^l equiv x ({ m{mod}} y) ]

    因为 (x ot y) ,则有:

    [k^l equiv k equiv 1 ({ m{mod}} y) implies y ot k ]

    那么分数 (frac{x}{y}) 当且仅当 (x ot y,y ot k) 才会对 ( ext{Ans}) 产生贡献。

    证毕。


    接下来就开始推式子。

    将式子中 ([x ot y]) 用莫比乌斯函数替换:

    [egin{align} sum_{x=1}^{n}sum_{y=1}^{m}[x ot y][y ot k] & = sum_{x=1}^{n}sum_{y=1}^{m}[y ot k]sum_{d|x,d|y} mu(d)\ &=sum_{d=1}^{{ m{min}}(n,m)}mu(d) lfloorfrac{n}{d} floorsum_{y=1}^{lfloorfrac{m}{d} floor} [yd ot k]=sum_{d=1}^{{ m{min}}(n,m)}mu(d) lfloorfrac{n}{d} floorsum_{y=1}^{lfloorfrac{m}{d} floor} [y ot k][d ot k]\ &=sum_{d=1}^{{ m{min}}(n,m)}mu(d)[d ot k] lfloorfrac{n}{d} floorsum_{y=1}^{lfloorfrac{m}{d} floor} [y ot k] end{align} ]

    如果我们能快速求出 (sum_{y=1}^{lfloorfrac{m}{d} floor} [y ot k])(mu(d)[d ot k]) 的前缀和,那么用整除分块就容易得到 ( ext{Ans})

    首先不难看出 (k) 中多个相同的质因子对 (k) 与其他数是否互质没有影响,所以不妨假设 (k) 的所有质因子次数均为1。

    令:

    [f(n,k)=sum_{i=1}^n[i ot k]\ g(n,k)=sum_{i=1}^nmu(i)[i ot k] ]

    那么 (f(n,1)=sum_{i=1}^n1=n) 能直接得出, (g(n,1)=sum_{i=1}^nmu(i)) 能通过杜教筛得出。

    考虑 (k ot = 1) 的情况:

    对于 (k) 的一个质因子 (p) ,考虑 (f(n,k)) 如何由 (f(n,frac{k}{p})) 得来。

    由于多了一个质因子,则与 (frac{k}{p}) 互质的数中有一些不与 (k) 互质,即能被 (p) 整除的数。所以(f(n,k)) 要从 (f(n,frac{k}{p})) 中去掉一部分:

    [egin{align} f(n,k)&=sum_{i=1}^{n}[i ot k]=sum_{i=1}^n[i ot frac{k}{p}]-sum_{i=1}^n[iot frac{k}{p}][p|i]\ &=f(n,frac{k}{p})-sum_{i=1}^{lfloorfrac{n}{p} floor}[ipot frac{k}{p}] end{align} ]

    因为 (p) 不存在于 (frac{k}{p}) 中,则有 ([ip ot frac{k}{p}]=[i ot frac{k}{p}]) ,则:

    [f(n,k)=f(n,frac{k}{p})-sum_{i=1}^{lfloorfrac{n}{p} floor}[iot frac{k}{p}]=f(n,frac{k}{p})-f(lfloorfrac{n}{p} floor,frac{k}{p}) ]

    类似的,有:

    [egin{align} g(n,k)&=sum_{i=1}^nmu(i)[iot k]=sum_{i=1}^nmu(i)[iot frac{k}{p}]-sum_{i=1}^nmu(i)[iot frac{k}{p}][p|i]\ &=g(n,frac{k}{p})-sum_{i=1}^{lfloorfrac{n}{p} floor}mu(ip)[iot frac{k}{p}] end{align} ]

    对于莫比乌斯函数,有:

    [mu(ij)=mu(i)mu(j)[iot j] ]

    代入上式得:

    [egin{align} g(n,k)&=g(n,frac{k}{p})-sum_{i=1}^{lfloorfrac{n}{p} floor}mu(ip)[iot frac{k}{p}]\ &=g(n,frac{k}{p})-sum_{i=1}^{lfloorfrac{n}{p} floor}mu(i)mu(p)[iot p][iot frac{k}{p}]\ &=g(n,frac{k}{p})+sum_{i=1}^{lfloorfrac{n}{p} floor}mu(i)[iot k]\ &=g(n,frac{k}{p})+g(lfloorfrac{n}{p} floor,k) end{align} ]

    递归求一下 (f,g) ,这道题就被完美解决了。


    ( ext{Code}:)

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <unordered_map>
    #define maxn 10000005
    #define Rint register int
    #define INF 0x3f3f3f3f
    using namespace std;
    typedef long long lxl;
    
    template <typename T>
    inline T read()
    {
    	T x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    	return x*f;
    }
    
    int prime[maxn],cnt;
    bool flag[maxn];
    lxl mu[maxn];
    lxl N,M,K,pri[maxn],prc;
    
    inline void sieve()
    {
    	mu[1]=1;
    	for(int i=2;i<maxn;++i)
    	{
    		if(!flag[i]) prime[++cnt]=i,mu[i]=-1;
    		for(int j=1;j<=cnt&&i*prime[j]<maxn;++j)
    		{
    			flag[i*prime[j]]=true;
    			if(!(i%prime[j])) break;
    			mu[i*prime[j]]=-mu[i];
    		}
    	}
    	for(int i=1;i<maxn;++i)
    		mu[i]+=mu[i-1];
    	for(int i=1;i<=cnt;++i)
    	{
    		while(!(K%(prime[i]*prime[i]))) K/=prime[i];
    		if(!(K%prime[i])) pri[++prc]=prime[i];
    	}
    }
    
    unordered_map<int,lxl> mp;
    
    inline lxl G1(int n)
    {
    	if(n<maxn) return mu[n];
    	if(mp[n]) return mp[n];
    	lxl res=1;
    	for(lxl l=2,r=0;l<=n;l=r+1)
    	{
    		r=n/(n/l);
    		res-=(r-l+1)*G1(n/l);
    	}
    	return mp[n]=res;
    }
    
    unordered_map<int,unordered_map<int,lxl> > F,G;
    
    inline lxl f(int n,int k,int p=1)
    {
    	if(!n) return 0;
    	if(k==1) return 1ll*n;
    	if(F[n][k]) return F[n][k];
    	return F[n][k]=f(n,k/pri[p],p+1)-f(n/pri[p],k/pri[p],p+1);
    }
    
    inline lxl g(int n,int k,int p=1)
    {
    	if(!n) return 0;
    	if(k==1) return G1(n);
    	if(G[n][k]) return G[n][k];
    	return G[n][k]=g(n,k/pri[p],p+1)+g(n/pri[p],k,p);
    }
    
    int main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("P1587.in","r",stdin);
    #endif
    	N=read<int >(),M=read<int >(),K=read<int >();
    	sieve();
    	lxl res=0;
    	int up=min(N,M);
    	for(lxl l=1,r=0;l<=up;l=r+1)
    	{
    		r=min(N/(N/l),M/(M/l));
    		res+=1ll*(N/l)*f(M/l,K)*(g(r,K)-g(l-1,K));
    	}
    	printf("%lld
    ",res);
    	return 0;
    }
    
    

    参考文献:

    神犇柳苏明的题解

    11Dimensions的课件。

  • 相关阅读:
    about_并查集
    MST_prim
    MST_kruskal
    物联网的未来:关于物联网的10个预测
    如何展现云计算安全领导力
    虚拟机发展依然强劲,但会被容器取代吗?
    如何从人工智能部署中获取最大价值
    维特根斯坦:为何夸大人工智能是对人性的贬损?
    区块链技术还在不断创新
    区块链真正能用来干什么?这5件事说清楚了
  • 原文地址:https://www.cnblogs.com/syc233/p/13543303.html
Copyright © 2011-2022 走看看