zoukankan      html  css  js  c++  java
  • CF 900D Unusual Sequences

    题目链接
    (Description)
    给定(x,y),求有多少个数列满足(gcd(a_i)=x且sum a_i=y)。答案对(10^9+7)取模。

    (1≤x,y≤10^9)


    (Solution)
    (y)如果不是(x)的倍数,答案为(0)

    然后呢

    (y/=x),问题就变成了求有多少个数列满足(gcd(a_i)=1且sum ai=y')

    如果没有(gcd)(1)的限制?
    隔板法可得(ans=sum_{i=0}^{y-1}C_{y-1}^i=2^{y-1})

    (f(i))表示(gcd(a_i)=1)且和为(i)的方案数,(g(i))表示和为(i)的方案数。
    可得

    [g(i)=2^i-1,g(i)=sum_{d|i}f(d) ]

    要求的是(f(i)),所以把(f(i))的一项单独拿出来

    [f(i)=g(i)-sum_{d|i,d ot = i}f(d) ]

    然后就可以从前往后递推了。

    复杂度(O(d(y/x)^2)),其中(d(x))(x)的约数个数。

    当然$$g(i)=sum_{d|i}f(d)$$
    就是一般的莫比乌斯反演的形式。
    可以直接得出

    [f(i)=sum_{d|i}mu(d)g(frac{i}{d}) ]

    #include<complex>
    #include<cstdio>
    using namespace std;
    const int mod=1e9+7;
    const int N=1e5+7;
    int x,y,tot;
    int d[N];
    int qread()
    {
    	int x=0;
    	char ch=getchar();
    	while(ch<'0' || ch>'9')ch=getchar();
    	while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    	return x;
    }
    int GetMu(int x)
    {
    	if(x==1)return 1;
    	int t=0,sqr=sqrt(x);
    	for(int i=2;i<=sqr;i++)
    		if(x%i==0)
    		{
    			t++;x/=i;
    			if(x%i==0)return 0;
    		}
    	if(x>1)t++;
    	return t&1?-1:1;
    }
    int Fpow(long long b,int p)
    {
    	long long res=1;
    	for(;p;p>>=1,b=b*b%mod)
    		if(p&1)res=res*b%mod;
    	return res;
    }
    int main()
    {
    	scanf("%d%d",&x,&y);
    	if(y%x){printf("0
    ");return 0;}
    	y/=x;
    	for(int i=1;i*i<=y;i++)
    		if(y%i==0)
    		{
    			d[++tot]=i;
    			if(i*i!=y)d[++tot]=y/i;
    		}
    	long long ans=0;
    	for(int i=1;i<=tot;i++)
    		ans+=GetMu(y/d[i])*Fpow(2,d[i]-1);
    	printf("%d
    ",(ans%mod+mod)%mod);
    	return 0;
    }
    
  • 相关阅读:
    磁盘管理
    TCP/IP四层模型
    OSI七层模型详解
    kvm虚拟机
    mount 文件挂载
    ORA-01017: 用户名/口令无效; 登录被拒绝
    mybatis配置文件形式
    Spring+mybatis整合
    xmlBean学习二
    xmlBean学习一
  • 原文地址:https://www.cnblogs.com/LeTri/p/10322503.html
Copyright © 2011-2022 走看看