HDU 5514 Frogs (容斥原理)
题目链接 : http://acm.hdu.edu.cn/showproblem.php?pid=5514
题意 :
有m个石子围成一圈, 有n只青蛙从跳石子, 都从0号石子开始, 每只能越过a[i]个石子
问所有被至少踩过一次的石子的序号之和
思路 :
不难发现, 从0开始, 每次越过a[i]个石子, 那么gcd(a[i], m)的倍数都能被经过
石子 k * (gcd(a[i], m)) < m 的都被算入
但如果按单独每个a[i]来计算对答案的贡献, 肯定会有重复, 重复部分就是lcm(a[i], a[j])的倍数
这里要用容斥的思想解决
第一次正式接触容斥, 但其实已经有很多地方用过这种思想了
比如二维树状数组求面积, 求一个范围内能整除若干个数的个数, 还有某些概率计算
这道题中, 考虑每个gcd(a[i], m)的贡献时
首先 x = gcd(a[i], m) 一定是m的因子, x的贡献是 (m / x) * (m / x - 1) * / 2 * x
因为Sum(k * x) (1 <= k < m / x), 提取x为公因子, k就是一个等差数列求和
此时若有 y = gcd(a[j], m), y % x == 0, 则要减去一次y产生的贡献
所以解法是, 先用处理出所有m的因子, 储存在一个数组d中
对每个a[i], 都算出x = gcd(a[i], m), 遍历m的因子,
若d[i] % m == 0, 就将这个因子的贡献标记为1, vis[i] = 1, 表示这个因子应该做贡献
用一个数组记录每个因子做过的贡献, 一开始全为0
再遍历m的因子, 如果当前这个因子应该做的贡献和已经做的贡献不等, 补上贡献的次数是vis[i] - num[i]
所以套用计算贡献的公式, 当前因子x做的贡献为(m / x) * (m / x - 1) * / 2 * x * (vis[i] - num[i])
这时就要用容斥了, 这些因子中, 如果有y能整除x, x进行贡献的同时, 因子y也同时被贡献了vis[i] - num[i]次
那么对应因子y的num[j]就要加上vis[i] - num[i]
如果出现了vis[i] - num[i] < 0的情况, 说明这个因子被多贡献了, 减去相应次数的贡献即可
重现没有做出来, 代码是参考了网上大牛的
#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; typedef long long LL; const int MAXN = 1e4+; int a[MAXN];
int d[MAXN];
int vis[MAXN];
int num[MAXN]; int GCD(int a, int b)
{
int r = a % b;
while(r) {
a = b;
b = r;
r = a % b;
}
return b;
} bool cmp(int a, int b)
{
return a < b;
} void Init()
{
memset(vis, , sizeof(vis));
memset(num, , sizeof(num));
} int main()
{
int t;
int n, m; scanf("%d", &t);
for(int cas = ; cas <= t; cas++) {
Init();
scanf("%d %d", &n, &m);
int cnt = ;
for(int i = ; i * i <= m; i++) {
if(m % i == ) {
d[cnt++] = i;
if(i * i != m) {
d[cnt++] = m / i;
}
}
}
sort(d, d+cnt, cmp);
for(int i = ; i < n; i++) {
scanf("%d", &a[i]);
a[i] = GCD(a[i], m);
for(int j = ; j < cnt; j++) {
if(d[j] % a[i] == ) {
vis[j] = ;
}
}
}
LL ans = ;
vis[cnt-] = ;
for(int i = ; i < cnt; i++) {
if(vis[i] != num[i]) {
LL temp = m / d[i];
ans += temp * (temp - ) / * d[i] * (vis[i] - num[i]);
for(int j = i + ; j < cnt; j++) {
if(d[j] % d[i] == ) {
num[j] += vis[i] - num[i];
}
}
}
}
printf("Case #%d: %I64d\n", cas, ans);
} return ;
}
HDU 5514 Frogs (容斥原理)的更多相关文章
- HDU 5514 Frogs (容斥原理+因子分解)
题目链接 题意:有n只青蛙,m个石头(围成圆圈).第i只青蛙每次只能条ai个石头,问最后所有青蛙跳过的石头的下标总和是多少? 题解:暴力肯定会超时,首先分解出m的因子,自己本身不用分,因为石头编号是0 ...
- hdu 5514 Frogs(容斥)
Frogs Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submi ...
- HDU 5514 Frogs(容斥原理)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5514 [题目大意] m个石子围成一圈,标号为0~m-1,现在有n只青蛙,每只每次跳a[i]个石子, ...
- HDU 5514 Frogs 容斥定理
Frogs Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5514 De ...
- HDU 5514 Frogs
Frogs Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on HDU. Original ID: 5514 ...
- HDU 5514 Frogs 欧拉函数
题意: 有\(m(1 \leq m \leq 10^9)\)个石子排成一圈,编号分别为\(0,1,2 \cdots m-1\). 现在在\(0\)号石头上有\(n(1 \leq n \leq 10^4 ...
- HDU 5514 Frogs (数论容斥)
题意:有n只青蛙,m个石头(围成圆圈).第i只青蛙每次只能条ai个石头,问最后所有青蛙跳过的石头的下标总和是多少? 析:首先可以知道的是第 i 只青蛙可以跳到 k * gcd(ai, m),然后我就计 ...
- hdu 5514 Frogs 容斥思想+gcd 银牌题
Frogs Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submi ...
- HDU 5514.Frogs-欧拉函数 or 容斥原理
Frogs Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submi ...
随机推荐
- POJ 2891 扩展欧几里德
这个题乍一看跟剩余定理似的,但是它不满足两两互素的条件,所以不能用剩余定理,也是给了一组同余方程,找出一个X满足这些方程,如果找不到的话就输出-1 因为它不满足互素的条件,所以两个两个的合并,最后合成 ...
- 001-视频 video
<!DOCTYPE HTML> <html> <body> <video width="320" height="240&quo ...
- Android中Application全局方法(变量)的调用
Application和Actovotu,Service一样是android框架的一个系统组件,当android程序启动时系统会创建一个 application对象,用来存储系统的一些信息.通常我们是 ...
- Solution(项目部署):The server does not support version 3.0 of the J2EE Web module specification
1.错误: 在eclipse中使用run->run on server的时候,选择tomcat6会报错误:The server does not support version 3.0 of t ...
- java解析JSON (使用net.sf.json)
例如JSON字符串str如下: { "data": [ { "basic_title": "运筹帷幄因 ...
- underscorejs-find学习
2.5 find 2.5.1 语法: _.find(list, predicate, [context]) 2.5.2 说明: 对list集合的每个成员依次进行匹配(根据predicate迭代函数检测 ...
- unset() isset() empty difined()操作变量详解
isset()函数 一般用来检测变量是否设置 格式:bool isset ( mixed var [, mixed var [, ...]] ) 功能:检测变量是否设置 返回值: 若变量不存在则返 ...
- Dede 列表文章 自增
在{dede:arclist/}这个标签中有个[field:global.autoindex/],是从0开始自增,如果我们想自定义一个数值,比如自定义从2开始.那么就可以写成下面代码: [field: ...
- Python自动化运维之17、Python操作 Memcache、Redis、RabbitMQ
一.Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的 ...
- jquery如何判断滚动条滚到页面底部并执行事件
首先理解三个dom元素,分别是:clientHeight.offsetHeight.scrollTop. clientHeight:这个元素的高度,占用整个空间的高度,所以,如果一个div有滚动条,那 ...