zoukankan      html  css  js  c++  java
  • luogu 1587 [NOI2016]循环之美

    LINK:NOI2016循环之美

    这道题是 给出n m k 求出(1leq ileq n,1leq jleq m) (frac{i}{j})在k进制下是一个纯循环的。

    由于数值相同的分数不能记录 所以 ((i,j)==1) 对于是一个纯循环的数我们先从最熟悉的10进制下说起。

    可以发现(frac{1}{7},frac{1}{13})等等都是纯循环的 而(frac{1}{6},frac{1}{4})等等非纯循环。

    于是可以发现 当j和10互质的时候此时是纯循环。不妨证明这一点。

    当 j和10互质的时候 可以发现j和10没有共有的因子所以(10^w)在mod j的情况下是有循环的。这类似于完全剩余系。

    当j和10不互质 时 显然可以发现 前半部分时非循环后半部分由于因数被消掉之后 剩下和10互质的数 所以后半部分时一个循环 但此时已经不满足条件了。

    从10 我们发现一个有意思的时候 那就是我们好像可以推广到K进制 在K进制下也是一个纯循环的数当且仅当 j在K进制下和K互质。

    举个例子 在5进制下 (frac{3}{4}) 4和5 互质 而且你可以自己手算一下这个结果是0.33333333 在5进制下。

    说明我们假设成立。(考场上还是要靠猜的。

    但是这样求还是很困难 因为j在K进制下和K互质 nm暴力之外还要把 j转成K进制 还要再求gcd 这着实优化不了。

    O(m)暴力我们都T掉了。

    考虑两个数字互质有 (a,b)==1 在K进制下 ((...+p_1k^1+p_0k^0,...+b_1k^1+b_0k^0))这个东西gcd会是多少呢

    我猜测是1 /cy 通过不断的打表发现是正确的。于是不考虑证明我们得到这样的一个式子。

    题目要求的是 (sumlimits_{i=1}^{n}sumlimits_{j=1}^{m}[(i,j)=1][(j,k)=1])

    随便变型一下:(sumlimits_{i=1}^{n}sumlimits_{j=1,且(j,k)=1}^{m}sum_{d|i,d|j}mu(d))

    ( o sum_{d=1}^{n}mu(d)frac{n}{d}sum_{j=1}^{frac{m}{d}}[(jd,k)=1])

    你发现都推到这里了 还是很难求。

    但是到了这个地方再把互质的条件进行反演会非常繁杂。

    一般到这个时候直接整除分块。所以我们只需要考虑 (sum_{d=1}^{n}[(d,k)=1]mu(d))这个东西和(sum_{j=1}^{frac{m}{d}}[(j,k)=1])的前缀和即可。

    先考虑后面 设函数g(x)表示 (sum_{i=1}{x}[(i,k)=1]) 那么(g(x)=frac{x}{k}g(k)+g(xmod k))

    那么预处理g函数很简单 O(k)枚举暴力算即可。

    考虑前面那个东西的前缀和 (S(n,k)=sum_{d=1}^{n}mu(d)[(d,k)=1])

    这个时候没有什么办法化简了 而直接求是复杂度很高。

    反演一下 (S(n,k)=sum_{d=1}^{n}mu(d)sum_{x|d,x|k}mu(x))

    (S(n,k)=sum_{x|k}mu(x)sum_{d=1}{frac{n}{x}}mu(xd))

    这个时候 看起来没办法化简了 但是其实我们观察一下(mu(xd)) ((x,d) eq 1)时 对答案才有贡献。

    由积性函数可得 (S(n,k)=sum_{x|k}mu(x)sum_{d=1}{frac{n}{x}}mu(d)mu(x)[(x,d)=1])

    根据我们S函数的定义可得 (sum_{d=1}{frac{n}{x}}mu(d)mu(x)[(x,d)=1])

    所以总式子为(S(n,k)=sum_{x|k}mu(x)^2 S(frac{n}{x},d))

    所以这个S函数可以递归的算出来 我们利用map存起来来加快速度 对于mu(x)==0的可以不算。

    显然递归边界为x==1 这个时候观察原式 其实式求(mu(x))的前缀和。

    所以我们杜教筛一下。这样就可以求了。注意求S的时候也要开map来加速 还需要判断一下边界什么的。

    复杂度?关于S的求出我并不会 分析复杂度。

    const int MAXN=5000010,maxn=2010;
    int n,m,k,top,maxx=5000000;
    int mu[MAXN],p[MAXN],v[MAXN],g[maxn],w[MAXN];
    inline int gcd(int a,int b){return b?gcd(b,a%b):a;}
    map<int,int>H;map<pii,ll>s;
    inline void prepare()
    {
    	rep(1,k,i){g[i]+=g[i-1];if(gcd(i,k)==1)++g[i];}
    	mu[1]=1;
    	rep(2,maxx,i)
    	{
    		if(!v[i])
    		{
    			p[++top]=v[i]=i;
    			mu[i]=-1;
    		}
    		rep(1,top,j)
    		{
    			if(maxx/i<p[j])break;
    			v[i*p[j]]=p[j];
    			if(v[i]==p[j])break;
    			mu[i*p[j]]=-mu[i];
    		}
    	}
    	rep(1,maxx,i)w[i]+=w[i-1]+mu[i];
    }
    inline int djs(int x)
    {
    	if(x<=maxx)return w[x];
    	if(H.find(x)!=H.end())return H[x];
    	int ans=1;
    	int w,ww;
    	for(int i=2;i<=x;i=ww+1)
    	{
    		w=x/i;ww=x/w;
    		ans-=(ww-i+1)*djs(w);
    	}
    	H[x]=ans;return ans;
    }
    inline ll S(int n,int k)
    {
    	if(k==1)return djs(n);
    	if(n==1)return 1;
    	if(!n)return 0;
    	if(s.find(mk(n,k))!=s.end())return s[mk(n,k)];
    	ll ans=0;
    	for(int i=1;i*i<=k;++i)
    	{
    		if(k%i==0)
    		{
    			if(mu[i])ans=ans+S(n/i,i);
    			if(mu[k/i]&&i*i!=k)ans=ans+S(n/(k/i),k/i);
    		}
    	}
    	s[mk(n,k)]=ans;
    	return ans;
    }
    inline ll G(ll x){return x/k*g[k]+g[x%k];}
    int main()
    {
    	//freopen("1.in","r",stdin);
    	get(n);get(m);get(k);
    	prepare();
    	int w1,w2,ww;
    	ll ans=0;
    	int cc=min(n,m);
    	for(RE int i=1;i<=cc;i=ww+1)
    	{
    		w1=n/i;w2=m/i;
    		ww=min(n/w1,m/w2);
    		ans=ans+w1*(S(ww,k)-S(i-1,k))*G(w2);
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    bzoj1042 [ HAOI2008 ] --容斥原理+完全背包
    bzoj1079 [ SCOI2008 ] --记忆化搜索
    bzoj1584 [ Usaco2009 Mar ] --DP
    bzoj4724 [ POI2017 ] --数论
    bzoj3208--记忆化搜索
    bzoj3095--数学题
    resque 遍历加载job目录下的类
    php,js清除cookie
    nginx 设置 fastcgi缓存
    php缓冲区 sapi缓冲区
  • 原文地址:https://www.cnblogs.com/chdy/p/12511278.html
Copyright © 2011-2022 走看看