Frogs

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 4843    Accepted Submission(s): 1605

Problem Description
There are m stones lying on a circle, and n frogs are jumping over them.
The stones are numbered from 0 to m−1 and the frogs are numbered from 1 to n. The i-th frog can jump over exactly ai stones in a single step, which means from stone j mod m to stone (j+ai) mod m (since all stones lie on a circle).

All frogs start their jump at stone 0, then each of them can jump as many steps as he wants. A frog will occupy a stone when he reach it, and he will keep jumping to occupy as much stones as possible. A stone is still considered ``occupied" after a frog jumped away.
They would like to know which stones can be occupied by at least one of them. Since there may be too many stones, the frogs only want to know the sum of those stones' identifiers.

 
Input
There are multiple test cases (no more than 20), and the first line contains an integer t,
meaning the total number of test cases.

For each test case, the first line contains two positive integer n and m - the number of frogs and stones respectively (1≤n≤10^4 1≤m≤10^9).

The second line contains n integers a1,a2,⋯,an, where ai denotes step length of the i-th frog (1≤ai≤10^9).

 
Output
For each test case, you should print first the identifier of the test case and then the sum of all occupied stones' identifiers.
 
Sample Input
3
2 12
9 10
3 60
22 33 66
9 96
81 40 48 32 64 16 96 42 72
 
Sample Output
Case #1: 42
Case #2: 1170
Case #3: 1872
 
Source

解析  这道题真的非常好,有技巧的容斥。

AC代码

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<math.h>
using namespace std;
#define maxn 10005
int gcd(int a,int b)
{
return b==?a:gcd(b,a%b);
}
//每个青蛙,可以跳到gcd(m,a[i])*k的位置
int ppp[maxn];
int num[maxn],vis[maxn];
int main()
{
int tt;scanf("%d",&tt);
for(int cas=;cas<=tt;cas++)
{
int n,m;
int cnt = ;
memset(vis,,sizeof(vis));
memset(num,,sizeof(num));
scanf("%d%d",&n,&m);
for(int i=;i<=sqrt(m);i++)//把因子全部筛出来
{
if(m%i==)
{
ppp[cnt++]=i;
if(i*i!=m)
ppp[cnt++]=m/i;
}
}
sort(ppp,ppp+cnt);
for(int i=;i<n;i++)
{
int x;scanf("%d",&x);
int kk = gcd(x,m);
for(int j=;j<cnt;j++)
if(ppp[j]%kk==)//说明这个因子的所有,都是可以被跳到的位置
vis[j]=;
}
vis[cnt-]=;//显然 m是不可能被跳到的
long long ans = ;
for(int i = ; i < cnt; i++)
{
if(vis[i] != num[i])
{
int t = (m-)/ppp[i];
ans += (long long)t*(t+)/ * ppp[i] * (vis[i]-num[i]);
//容斥一波
//一开始vis[i] - num[i] = 1的
//对于每个因数,如果重复计算了,在之后,减去就好了
t = vis[i] - num[i];
for(int j = i; j < cnt; j++)
if(ppp[j]%ppp[i] == )
num[j] += t;
}
}
printf("Case #%d: %lld\n",cas,ans);
}
}

wa的代码,暴力容斥,极限数据是36个gcd 应该直接爆复杂度了,不应该是wa的

#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(a) (a).begin(), (a).end()
#define fillchar(a, x) memset(a, x, sizeof(a))
#define huan printf("\n")
#define debug(a,b) cout<<a<<" "<<b<<" "<<endl
#define ffread(a) fastIO::read(a)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn=1e4+;
ll gcd(ll a,ll b)
{
return b?gcd(b,a%b):a;
}
ll sum(ll x,ll n)
{
ll temp=(n-)/x;
return temp*x+(temp*(temp-)/)*x;
}
int main()
{
ll t,n,m;
int kase=;
scanf("%lld",&t);
while(t--)
{
set<ll> s;
scanf("%lld%lld",&n,&m);
for(int i=;i<n;i++)
{
ll x;
scanf("%lld",&x);
s.insert(gcd(x,m));
}
vector<ll> g;
for(auto it:s)
{
int flag=;
for(auto itt:s)
if(it%itt==&&it!=itt)
flag=;
if(flag)g.pb(it);
}
ll cnt=g.size();
ll ans=;
for(ll i=; i<(1ll<<cnt); i++)
{
ll temp=,jishu=;
for(ll j=; j<cnt; j++)
{
if(i&(<<j))
temp=temp*g[j]/gcd(g[j],temp),jishu++;
}
if(jishu==)
continue;
if(jishu%==)
ans+=sum(temp,m);
else
ans-=sum(temp,m);
}
printf("Case #%d: %lld\n",kase++,ans);
}
}

HDU 5514 容斥原理的更多相关文章

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

    Frogs Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

  2. hdu 5514 Frogs(容斥)

    Frogs Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

  3. GCD HDU - 1695 容斥原理(复杂度低的版本)

    题意: 让你从区间[a,b]里面找一个数x,在区间[c,d]里面找一个数y.题目上已经设定a=b=1了.问你能找到多少对GCD(x,y)=k.x=5,y=7和y=5,x=7是同一对 题解: 弄了半天才 ...

  4. - Visible Trees HDU - 2841 容斥原理

    题意: 给你一个n*m的矩形,在1到m行,和1到n列上都有一棵树,问你站在(0,0)位置能看到多少棵树 题解: 用(x,y)表示某棵树的位置,那么只要x与y互质,那么这棵树就能被看到.不互质的话说明前 ...

  5. HDU 5514 Frogs (容斥原理)

    题目链接 : http://acm.hdu.edu.cn/showproblem.php?pid=5514 题意 : 有m个石子围成一圈, 有n只青蛙从跳石子, 都从0号石子开始, 每只能越过a[i] ...

  6. HDU 5514 Frogs(容斥原理)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5514 [题目大意] m个石子围成一圈,标号为0~m-1,现在有n只青蛙,每只每次跳a[i]个石子, ...

  7. HDU 5514 Frogs (容斥原理+因子分解)

    题目链接 题意:有n只青蛙,m个石头(围成圆圈).第i只青蛙每次只能条ai个石头,问最后所有青蛙跳过的石头的下标总和是多少? 题解:暴力肯定会超时,首先分解出m的因子,自己本身不用分,因为石头编号是0 ...

  8. HDU 4059 容斥原理+快速幂+逆元

    E - The Boss on Mars Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64 ...

  9. HDU 5514 Frogs 容斥定理

    Frogs Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5514 De ...

随机推荐

  1. js中传统事件绑定模拟现代事件处理

    大家都知道,IE中的现代事件绑定(attachEvent)与W3C标准的(addEventListener)相比存在很多问题, 例如:内存泄漏,重复添加事件并触发的时候是倒叙执行等. 下面是用传统事件 ...

  2. How to proxy a web site by apache2 in Ubuntu

    Install apache2 To execute the install command in terminal: sudo apt-get install apache2 Then, we ca ...

  3. Web框架_MVC vs MVT

    MVC 大部分开发语言中都有MVC框架 MVC框架的核心思想是:解耦 降低各功能模块之间的耦合性,方便变更,更容易重构代码,最大程度上实现代码的重用 M表示model,主要用于对数据库层的封装 V表示 ...

  4. 谷歌 滚动条样式 scrollbar

    谷歌  滚动条样式 scrollbar main.less :: 是css3 最新的伪类 /*滚动条整体样式*/ ::-webkit-scrollbar { width: 10px; height: ...

  5. C++类的存储及虚函数实现原理

    一.C++成员函数在内存中的存储方式 用类去定义对象时,系统会为每一个对象分配存储空间.如果一个类包括了数据和函数,要分别为数据和函数的代码分配存储空间.按理说,如果用同一个类定义了10个对象,那么就 ...

  6. Vue之组件的使用

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. Web前端技术体系大全搜索

    一.前端技术框架 1.Vue.js 官网:https://cn.vuejs.org/ Vue CLI:https://cli.vuejs.org/ 菜鸟教程:http://www.runoob.com ...

  8. Dubbo 源代码分析八:再说 Provider 线程池被 EXHAUSTED

    转自:http://manzhizhen.iteye.com/blog/2391177 在上回<Dubbo源代码实现六>中我们已经了解到,对于Dubbo集群中的Provider角色,有IO ...

  9. python数组中数据位置交换 -- IndexError: list assignment index out of range

    代码: t = [-10,-3,-100,-1000,-239,1] # 交换 -10和1的位置 t[5], t[t[5]-1] = t[t[5]-1], t[5] 报错: IndexError: l ...

  10. 【转载】form表单的两种提交方式,submit和button的用法

    1.当输入用户名和密码为空的时候,需要判断.这时候就用到了校验用户名和密码,这个需要在jsp的前端页面写:有两种方法,一种是用submit提交.一种是用button提交.方法一: 在jsp的前端页面的 ...