poj1091:跳蚤【容斥原理】

题目大意:中文题就不翻译了

思路:假设跳蚤选择X1个第一张卡片,X2个第二张卡片。。。Xn个第n张卡片,Xn+1张写着m的卡片,那么就可以列出方程:a1*X1+a2*X2+…+an*Xn+m*X(n+1)=1

由于可以向左跳和向右跳,因此题目即问上述不定方程是否有解?答案以及它的证明可以在任何一本数论书中找到,它的充要条件是(a1,a2,a3。。。an,m)|1 即a1,a2,a3。。。an,m互质,这样题目就成为:有n+1个正整数,其中最大的数为m,问所有符合条件的序列中有多少是互质的。

组合数学很多都是正难则反易的,考虑问题的背面有多少最大公约数不为1的?先把m分解质因数,m的每一个因子可以看成一个集合,集合中的元素为最大公约数为这个因子的序列,这个问题的答案便是所有集合的并中集合的元素,用容斥就显然了

最后将总数m^n减去最大公约数不为1的个数,结果就是互质的个数了

顺便吐槽下,虽然容斥属于集合论里面的东西,但经常用来证明数论题目,最早学它好像就是用来推导欧拉函数的公式时用的

#include <cstdio>

#include <string>

#include <iostream>

#include <math.h>

#define ll __int64

using namespace std;

llfactor[100000],h=0,stack[100000],top=0,mt,nt,ret1;

ll quickpow(ll n,ll m)

{

ll ret=1;

while (m)

{

if ((m & 1))ret*=n;

n*=n;

m>>=1;

}

return ret;

}

void dfs(ll step,ll now,ll layer,ll num)

{

if (step==layer){ret1+=quickpow(mt/num,nt);return ;}

for(inti=now+1;i<=h-layer+step+1;i++)dfs(step+1,now+1,layer,num*factor[i]);

}

int main()

{

ll n;

scanf("%I64d%I64d",&nt,&mt);

n=mt;

while ((n & 1)==0){h=1;factor[h]=2;n>>=1;}

ll q=sqrt(n);

for(ll i=3;i<=q && n!=1;i+=2)

{

if (n % i==0)factor[++h]=i;

while(n%i==0)n=n/i;

}

if (n!=1)factor[++h]=n;

ll ans=0,flag=-1;

for(ll i=1;i<=h;i++)

{

flag*=-1;

top=ret1=0;

dfs(0,0,i,1);

ans+=ret1*flag;

}

printf("%I64d\n",(ll)quickpow(mt,nt)-ans);

return 0;

}

时间: 2024-08-11 05:43:22

poj1091:跳蚤【容斥原理】的相关文章

poj1091跳蚤(容斥定理)

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

【poj1091】 跳蚤

http://poj.org/problem?id=1091 (题目链接) 题意 给出一张卡片,上面有n+1个数,其中最大的数为m,每次可以向前或者向后走卡片上面的步数.问有多少种方案选出n个数,使得存在一种走的方案经过若干步后可以达到与起点距离为1的位置上. Solution 今天考试题,又是一道大原题... 我们假设卡片上的数分别为:{a1,a2,a3,a4······an,m},那么如果要满足题目要求,就是说存在一个数列x:{x1,x2,x3,x4······xn,xn+1}使得a1x1+

[BZOJ1220][POJ1091][HNOI2002]跳蚤

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

poj1091 容斥原理的应用

这个题的意思是给你n+1个数, a1 a2 ... an an+1 其中 1<=ai<=M  i!=n+1  an+1 = M, 求解存在x1..xn+1使x1*a1+x2*a2+x3*a3+..+xn+1*an+1 = 1的a序列的个数, 由数论部分知识我们可以知道上式要满足就得使(a1, a2, a3, .. an, an+1) = 1,   我们还能知道存在一些a序列他们的最大公约数不等于1, 然而我们要统计其中最大公约数为1的个数, 就可以使用容斥原理, 稍加思考我们可以发现(a1,

容斥原理——poj1091

将m质因子分解,然后枚举选取的质因子个数i进行容斥,每种情况进行一次dfs即可 dfs结束标记:当质因子个数达到i时退出递归,同时累加该解对应的方案数 /* 给定n,m 共有n个数的数组a,不超过m m^n减掉 gcd(a)>1的情况 先把m质因数分解 然后枚举不同的质因子个数即可 */ #include<iostream> #include<cstring> #include<cstdio> using namespace std; #define ll lon

[HNOI2002]跳蚤

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

ACM 容斥原理

VJ 点击打开链接 参考 点击打开链接 非常好的译文:点击打开链接 容斥原理的想法就是求多个集合的并集.所以要先设计好集合. 组合数学问题中,正面解决会困难,常用方法是正难则反,使用容斥原理求反向在用全集减去.将对立面的限制条件分析清楚. eg 求区间互质的数的个数,则用除法等计算出一个数的倍数的方法再减去. UVa 11806 Cheerleaders 求k个石子放在n*m的矩阵里 并且第一行 最后一行 第一列 最后一列都要有石子 考虑反面 求出所有的 减去不满足的情况 容斥原理总共4个 集合

北大poj-1091

跳蚤 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9591   Accepted: 2892 Description Z 城市居住着很多只跳蚤.在Z城市周六生活频道有一个娱乐节目.一只跳蚤将被请上一个高空钢丝的正中央.钢丝很长,可以看作是无限长.节目主持人会给该跳蚤 发一张卡片.卡片上写有N+1个自然数.其中最后一个是M,而前N个数都不超过M,卡片上允许有相同的数字.跳蚤每次可以从卡片上任意选择一个自然数S, 然后向左

[HNOI 2002]跳蚤

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