容斥原理求一个数互质的数个数
2012-05-01 19:50
316 查看
1160: Confusion in the Problemset
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 107 Solved: 15
[Submit][Status][Web
Board]
Description
You are in an m x n grid. You are standing in position (0, 0) and in each of the other lattice points (points with integer co-ordinates) an enemy is waiting. Now you have a ray gun that can fire up to infinity and no obstaclecan stop it. Your target is to kill all the enemies. You have to find the minimum number of times you have to fire to kill all of them. For a 4 x 4 grid you have to fire 13 times. See the picture below:
Input
Input starts with an integer T (≤ 100), denoting the number of test cases.Each case contains two integers m, n (0 ≤ m, n ≤ 109) and at least one of them will be less than or equal to 106.
Output
For each case, print the case number and the minimum number of times you have to fire to kill all the enemies.Sample Input
24 410 10Sample Output
Case 1: 13Case 2: 65HINT
Source
LOJ1144#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long lld;
const int maxn=1000005;
bool mk[maxn];
int f[maxn];
int p[maxn];
int a[maxn];
void Gao()
{
int i,j;
for(i=1;i<maxn;i++)
{
p[i]=1; mk[i]=0;
}
for(i=2;i<maxn;i++)
if(!mk[i])
{
p[i]=f[i]=i;
for(j=i*2;j<maxn;j+=i)
{
f[j]=i;//记录j的最大质因子i
mk[j]=1;
p[j]*=i;//质因子的积
}
}
}
int main()
{
int T;
int cas=1,num,n,m;
int i,j,k;
int fact[15];
lld ans;
Gao();
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
if(n>m) n^=m^=n^=m;
if(n==0 ||m==0)
{
printf("Case %d: %d\n",cas++,(m^n)!=0);
continue ;
}
ans=2;
for(i=1;i<=n;i++)
{
if(i==p[i])
{
a[i]=num=0;
for(j=i;j!=1;j/=f[j])//求i的质因子
fact[num++]=f[j];
for(j=0;j<(1<<num);j++)//容斥原理
{
int tmp=1,sign=1;
for(k=0;k<num;k++)
if(j&(1<<k))
{
tmp*=fact[k];
sign=-sign;
}
a[i]+=m/tmp*sign;
}
}
ans+=a[p[i]];
}
printf("Case %d: %lld\n",cas++,ans);
}
return 0;
}
标程
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; struct point { int x,cnt; friend bool operator<(const point &p,const point &q){ return p.x<q.x; } }c[1000010]; int a[1100010],pri[1100010]; void prime() { memset(a,0,sizeof(a)); int i,j; for(i=2;i*i<=1100000;i++) if(!a[i]) for(j=i*i;j<=1100000;j+=i) a[j]=1; for(i=0,j=2;j<=1100000;j++) if(!a[j]) pri[i++]=j; } int cnt=0; void dfs(int mul,int pos,int step) { c[cnt].cnt=step; c[cnt++].x=mul; int up=1000000/mul; for(int i=pos;pri[i]<=up;i++){ dfs(mul*pri[i],i+1,step+1); } } int main() { prime(); dfs(1,0,0); sort(c,c+cnt); int t; scanf("%d",&t); for(int k=1;k<=t;k++){ long long n,m,ans=0; scanf("%lld%lld",&n,&m); for(int i=0;i<cnt;i++) if(c[i].x>min(n,m)) break; else if(c[i].cnt&1) ans-=(n/c[i].x)*(m/c[i].x); else ans+=(n/c[i].x)*(m/c[i].x); if(n==0&&m==0) ans=0; else if(n==0||m==0) ans=1; else ans+=2; printf("Case %d: %lld\n",k,ans); } return 0; }
相关文章推荐
- njust1922(容斥原理统计区间内与n互质的个数)
- HDU2841 一个关于互质的容斥
- 容斥原理求1到n与k互质个数
- hdu 1695 hdu 4135 容斥原理求1-n 区间内与r互质的个数
- 容斥原理 —— 求1~n有多少个数与k互质(二进制算法详细解释&模板)
- 【原理】看别人做了一个单页面换主题
- unity3d射线的原理用法以及一个利用射线实现简单拾取的小例子
- spring ioc原理(看完后大家可以自己写一个spring)
- 在刷一道题,数字回文,以以前做过,刚好昨天也做了一个类似的题,数字反转,原理有点像-----9. Palindrome Number
- spring ioc原理(看完后大家可以自己写一个spring)
- Dubbo入门-分布式原理详解--搭建一个最简单的Demo框架
- 容斥原理、鸽巢原理快速入门
- Skinned Mesh原理解析和一个最简单的实现示例
- 深入理解函数内部原理(2)——对一个函数实例进行深入的分析
- 添加默认路由的一个小例子以及原理
- Linux双网卡绑定一个IP原理及实现
- VC编译下对一个超简单的缓冲区溢出程序的原理解析以及c程序的汇编分析
- Unix编程学习笔记--------把一个库下载到系统中,那么这个库到底是什么??? 其内部的机制和原理是什么???
- 容斥原理应用--错排问题
- zoj 2836 Number Puzzle(容斥,求1到m有多少个数能被数组里任意一个整除)