HDU5514——容斥原理&&gcd

Posted lfri

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU5514——容斥原理&&gcd相关的知识,希望对你有一定的参考价值。

题目

链接

有n只青蛙,有m块石头,编号为0~m-1,第i只青蛙每次可以跳$a_i$, 刚开始都在0,问,青蛙总共可以跳到的石头之和为多少。其中$t≤20$,$1≤n≤10^4$,$1≤m≤10^9$,$1≤a_i≤10^9$.

分析

根据裴蜀定理知,对于一个有n个点的环,每个循环节的长度为n/gcd(n, k),k为每次走的步数。所以青蛙可以达到的石头编号肯定是$gcd(m,a_i)$的倍数,相当于真正步长为$gcd(m,a_i)$.

当然要容斥一下,不就是奇加偶减吗,枚举所有的项有$2^n$个($n$是gcd的个数),还要加剪枝,如果当前的lcm是gcd[i]的倍数,那么可以不继续容斥下去(也就是对答案没有贡献).

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 
 5 typedef long long ll;
 6 const int maxn = 100000 + 10;
 7 ll n, m;
 8 ll fac[maxn], cnt, sum;
 9 
10 ll gcd(ll a, ll b)
11 
12     return b == 0 ? a : gcd(b, a % b);
13 
14 ll lcm(ll a, ll b)
15 
16     return a * b / gcd(a, b);
17 
18 
19 void dfs(int pos, ll tlcm, int sz)
20 
21     //printf("pos:%d  tlcm:%lld  sz:%d\n", pos, tlcm, sz);
22     if(tlcm >= m)  return;
23     if(pos == cnt)
24     
25         if(sz == 0)  return;
26         if(sz & 1)
27         
28             ll tmp = (m-1) / tlcm;
29             sum += tmp * (tmp+1) * tlcm / 2;   //o  tlcm  2*tlcm... tmp*tlcm  奇加偶减
30         
31         else
32         
33             ll tmp = (m-1) / tlcm;
34             sum -= tmp * (tmp+1) * tlcm / 2;   //o  tlcm  2*tlcm... tmp*tlcm
35         
36         return;
37     
38     if(tlcm % fac[pos] == 0)  return;
39     dfs(pos+1, tlcm, sz);
40     dfs(pos+1, lcm(tlcm, fac[pos]), sz+1);
41 
42 
43 int main()
44 
45     int T, kase = 0;
46     scanf("%d", &T);
47     while(T--)
48     
49         scanf("%lld%lld", &n, &m);
50         bool flag= false;
51         for(int i = 0;i < n;i++)
52         
53             ll tmp;
54             scanf("%lld", &tmp);
55             fac[i] = gcd(tmp, m);
56             if(fac[i] == 1)  flag = true;
57         
58         printf("Case #%d: ", ++kase);
59         if(flag)
60         
61             printf("%lld\n", (m-1) * m / 2);
62         
63         else
64         
65             sort(fac, fac+n);
66             cnt = unique(fac, fac+n) - fac;
67             sum = 0;
68             dfs(0, 1, 0);
69             printf("%lld\n", sum);
70         
71     
72     return 0;
73 

网上更多的解法是分析m的因子,求贡献。(然而没有看懂

 

 

参考链接:http://www.acmtime.com/?p=864

以上是关于HDU5514——容斥原理&&gcd的主要内容,如果未能解决你的问题,请参考以下文章

HDU 5514 容斥原理

HDU 5514.Frogs-欧拉函数 or 容斥原理

HDU 5514 Frogs 容斥原理

HDU - 5514 Frogs(容斥原理)

hdu 5514Frogs

hdu 5514 Frogs(容斥)