zoukankan      html  css  js  c++  java
  • bzoj 1220 跳蚤

    Written with StackEdit.

    Description

    (Z)城市居住着很多只跳蚤。在(Z)城市周六生活频道有一个娱乐节目。一只跳蚤将被请上一个高空钢丝的正中央。钢丝很长,可以看作是无限长。节目主持人会给该跳蚤发一张卡片。卡片上写有(N+1)个自然数。其中最后一个是(M),而前(N)个数都不超过(M),卡片上允许有相同的数字。跳蚤每次可以从卡片上任意选择一个自然数(S),然后向左,或向右跳(S)个单位长度。而他最终的任务是跳到距离他左边一个单位长度的地方,并捡起位于那里的礼物。比如当(N=2,M=18)时,持有卡片((10, 15, 18))的跳蚤,就可以完成任务:他可以先向左跳(10)个单位长度,然后再连向左跳(3)次,每次(15)个单位长度,最后再向右连跳(3)次,每次(18)个单位长度。而持有卡片((12, 15, 18))的跳蚤,则怎么也不可能跳到距他左边一个单位长度的地方。当确定(N)(M)后,显然一共有(M^N)张不同的卡片。现在的问题是,在这所有的卡片中,有多少张可以完成任务。

    Input

    输入文件有且仅有一行,包括用空格分开的两个整数(N)(M)

    Output

    输出文件有且仅有一行,即可以完成任务的卡片数.(1≤M≤10^8,1≤N≤M,)(M^N≤10^16.)

    Sample Input

    2 4

    Sample Output

    12

    Solution

    • 显然,根据裴蜀定理,满足(gcd(a_1,a_2,a_3,......a_n,M)=1)的即为一组解.我们要对其进行计数.
    • 考虑用所有的方案(M^N)减去(gcd)不为(1)的数.
    • 因为最后一个数为(M),所以(gcd)一定是(M)的约数.
    • (M)分解质因数后,二进制枚举质因数的组合情况.
    • 若当前组合出来的数是(prod),那么是(prod)倍数的有(frac{p}{prod})个.
    • 那么这样的方案数为((frac{p}{prod})^N.)
    • 由于会产生重复计数,所以需要容斥处理.奇数个质因子(+),偶数个(-).

    这样看来,(M^N)也是一种特殊情况,(prod=1),个数为(0),所以用加.

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LoveLive;
    inline int read()
    {
    	int out=0,fh=1;
    	char jp=getchar();
    	while ((jp>'9'||jp<'0')&&jp!='-')
    		jp=getchar();
    	if (jp=='-')
    		{
    			fh=-1;
    			jp=getchar();
    		}
    	while (jp>='0'&&jp<='9')
    		{
    			out=out*10+jp-'0';
    			jp=getchar();
    		}
    	return out*fh;
    }
    int n,m;
    LoveLive fpow(LoveLive a,LoveLive b)
    {
    	LoveLive res=1;
    	while(b)
    		{
    			if(b&1)
    				res*=a;
    			a*=a;
    			b>>=1;
    		}
    	return res;
    }
    LoveLive factor[50];
    int main()
    {
    	n=read(),m=read();
    	LoveLive ans=fpow(m,n);
    	int p=m,siz=0;
    	for(int i=2;i*i<=p;++i)
    		if(p%i==0)
    			{
    				factor[++siz]=i;
    				while(p%i==0)
    					p/=i;
    			}
    	if(p>1)
    		factor[++siz]=p;
    	LoveLive lim=(1<<siz)-1;//质因数的组合方式,二进制枚举 
    	for(LoveLive i=1;i<=lim;++i)
    		{
    			LoveLive prod=1,cnt=0;//乘积与这种方案的质因数个数
    			for(int j=1;j<=siz;++j)
    				if((i>>(j-1))&1)
    					{
    						prod*=factor[j];
    						++cnt;
    					}
    			if(cnt&1)
    				ans-=fpow(m/prod,n);
    			else
    				ans+=fpow(m/prod,n);
    		}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    Python中Random随机数返回值方式
    SQL跨库查询
    正则表达式基本语法
    excel VBA使用教程
    使用某些Widows API时,明明包含了该头文件,却报错“error C2065: undeclared identifier”
    电脑开机后数字键盘为关闭状态
    编译Boost 详细步骤 适用 VC6 VS2003 VS2005 VS2008 VS2010
    变量作用域,不能理解,先记下
    解决MySQL 在 Java 检索遇到timestamp空值时报异常的问题
    Annotation
  • 原文地址:https://www.cnblogs.com/jklover/p/10107935.html
Copyright © 2011-2022 走看看