HDU 5514 Frogs (容斥原理+因子分解)
题意:有n只青蛙,m个石头(围成圆圈)。第i只青蛙每次只能条ai个石头,问最后所有青蛙跳过的石头的下标总和是多少?
题解:暴力肯定会超时,首先分解出m的因子,自己本身不用分,因为石头编号是0到m-1,第i只青蛙只能走到gcd(ai, m)的位置,我们就可以把m的因子提取出来,然后对青蛙能走到的因子位置打标记。两个数组,第一个数组a代表是否能走到该因子,第二个数组b表示是否已经加过了,加过了几次,遍历到那个因子的时候要加上(a[i]-b[i])倍的数,这个数很可能是负数。至于公式利用等差数列前n项和可以得出。
注意这道题是因子分解而不是素因子分解,因为对于12来说2和4是不一样的。
注意这道题不是对数进行操作而是对因子进行操作。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b)
{
return b==?a:gcd(b,a%b);
}
const int maxn=1e5+;
ll cnt=,prime[maxn];
void solve(ll m)
{
cnt=;//注意初始化
prime[cnt++]=;
for(int i=; i<sqrt(m); i++)
{
if(m%i==)
{
prime[cnt++]=i;
prime[cnt++]=m/i;
}
}
ll tmp=sqrt(m);
if(tmp*tmp==m)
prime[cnt++]=tmp;
sort(prime,prime+cnt);
}
int main()
{
int t,cas=;
scanf("%d",&t);
while(t--)
{
ll n,m,data,tmp;
scanf("%lld%lld",&n,&m);
memset(prime,,sizeof(prime));
solve(m);
ll a[maxn],b[maxn];
memset(a,,sizeof(a));//标记
memset(b,,sizeof(b));//算过了几次
for(int i=; i<n; i++)
{
scanf("%lld",&data);
tmp=gcd(data,m);
for(int j=; j<cnt; j++)
{
if(prime[j]%tmp==)
a[j]=;
}
}
ll ans=;
for(int i=; i<cnt; i++)
{
ll num=a[i]-b[i];
if(num!=)
{
ll tmp=(m-)/prime[i];
ans=ans+tmp*(tmp+)/*prime[i]*num;
for(int j=i; j<cnt; j++)
{
if(prime[j]%prime[i]==)
b[j]=b[j]+num; //注意是b表示数目
}
}
}
printf("Case #%d: %lld\n",cas++,ans);
}
return ;
}
更新版:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b)
{
return b==?a:gcd(b,a%b);
}
const int maxn=1e5+;
ll prime[maxn],a[maxn];
int cnt=;
void solve(ll m)
{
memset(a,,sizeof(a));
memset(prime,,sizeof(prime));
cnt=;
prime[cnt++]=;
for(int i=;i<sqrt(m);i++)
{
if(m%i==)
{
prime[cnt++]=i;
prime[cnt++]=m/i;
}
}
if(ll(sqrt(m))*ll(sqrt(m))==m) prime[cnt++]=ll(sqrt(m));
sort(prime,prime+cnt);
}
int main()
{
int t,cas=;
scanf("%d",&t);
while(t--)
{
ll n,m,data;
scanf("%lld%lld",&n,&m);
solve(m);
for(int i=;i<n;i++)
{
scanf("%lld",&data);
data=gcd(data,m);
for(int j=;j<cnt;j++)
if(prime[j]%data==) a[j]=;
}
ll ans=;
for(int i=;i<cnt;i++)
{
ll num=a[i];
if(num!=)
{
ll tmp=(m-)/prime[i];
ans+=tmp*(tmp+)/*prime[i]*num;
for(int j=i+;j<cnt;j++)
if(prime[j]%prime[i]==) a[j]-=num;
}
}
printf("Case #%d: %lld\n",cas++,ans);
}
return ;
}
HDU 5514 Frogs (容斥原理+因子分解)的更多相关文章
- HDU 5514 Frogs (容斥原理)
题目链接 : http://acm.hdu.edu.cn/showproblem.php?pid=5514 题意 : 有m个石子围成一圈, 有n只青蛙从跳石子, 都从0号石子开始, 每只能越过a[i] ...
- 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 ...
随机推荐
- php编程常用经验
1.用单引号代替双引号来包含字符串,这样做会更快一些.因为PHP会在双引号包围的字符串中搜寻变量, 单引号则不会,注意:只有echo能这么做,它是一种可以把多个字符串当作参数的"函数&quo ...
- MyEclipse------如何连接MySQL
testconnection.jsp <%@ page language="java" import="java.util.*" pageEncoding ...
- jquery发送ajax请求返回数据格式
jquery向服务器发送一个ajax请求后,可以返回多种类型的数据格式,包括:html,xml,json,text等. 1.html格式的数据 "<div class='comment ...
- make_pair
Utilities <utility> 由短小精干的类和函数构成,执行最一般性的工作. 这些工具包括: general types 一些重要的C函数 numeric limits Pair ...
- ios 判断控制器是否是第一次进入画页的做法
什么是第一次进入画页,只viewDidLoad一次: 所以只需要在viewDidLoad中加一个标识就行了. 加一个成员变量,或者属性,用来记录这个标识 一旦viewDidLoad后,这个就说明不是第 ...
- Linux下修改计算机名
SuSe操作系统: 1. 修改/etc/HOSTNAME 文件 ,其内容为计算机名. 输入命令:vi /etc/HOSTNAME 使用键盘上的 x 键一个一个删除所有内容 ,然后使用键盘上的 i ...
- httpModules与httpHandlers之httpModules(转载)
WapModule.cs:public class WapModule:IHttpModule{ public void Init(HttpApplication context) { ...
- heap和stack有什么区别
1.heap是堆,stack是栈. 2.stack的空间由操作系统自动分配和释放,heap的空间是手动申请和释放的,heap常用new关键字来分配. 3.stack空间有限,heap的空间是很大的自由 ...
- Java-Java中System.arraycopy() 和 Arrays.copyOf()两者之间的区别
如果我们想拷贝一个数组,我们可能会使用System.arraycopy()或者Arrays.copyof()两种方式.在这里,我们将使用一个比较简单的示例来阐述两者之间的区别. 1.示例代码: Sys ...
- motto3
在我看来,最努力的人不一定能收获最好的,但不努力的人是必定收获不到任何东西的. 所以,园主,你要会努力才行.否则,你会累死的. 用心去学,用脑去想,认真对待每一件事,聪明一点,不要太愚蠢.