Co-prime
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1517 Accepted Submission(s): 581
Problem Description
Given a number N, you are asked to count the number of integers between A and B inclusive which are relatively prime to N.
Two integers are said to be co-prime or relatively prime if they have no common positive divisors other than 1 or, equivalently, if their greatest common divisor is 1. The number 1 is relatively prime to every integer.
Two integers are said to be co-prime or relatively prime if they have no common positive divisors other than 1 or, equivalently, if their greatest common divisor is 1. The number 1 is relatively prime to every integer.
Input
The first line on input contains T (0 < T <= 100) the number of test cases, each of the next T lines contains three integers A, B, N where (1 <= A <= B <= 10
15) and (1 <=N <= 10
9).
Output
For each test case, print the number of integers between A and B inclusive which are relatively prime to N. Follow the output format below.
Sample Input
2 1 10 2 3 15 5
Sample Output
Case #1: 5 Case #2: 10HintIn the first test case, the five integers in range [1,10] which are relatively prime to 2 are {1,3,5,7,9}.
Source
The Third Lebanese Collegiate Programming Contest
最基本的模型:求[L,R]中与N互质的元素个数。
思路:容斥原理先考虑反面求与N不互质的个数,对N质因子分解,然后形成N的所有质因子的集合,然后枚举,进行容斥最后拿1-R中与N不互质的-1-L-1与N不互质的就OK了。
写不来DFS,只能用啥二进制暴力写了。。。
Total Submission(s): 4298 Accepted Submission(s): 1233
最基本的模型:求[L,R]中与N互质的元素个数。
思路:容斥原理先考虑反面求与N不互质的个数,对N质因子分解,然后形成N的所有质因子的集合,然后枚举,进行容斥最后拿1-R中与N不互质的-1-L-1与N不互质的就OK了。
写不来DFS,只能用啥二进制暴力写了。。。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
vector<long long> v;
long long a,b,n;
long long solve(long long x,long long n)
{
v.clear();
for(long long i=2;i*i<=n;i++)
{
if(n%i==0)
{
v.push_back(i);
while(n%i==0)
{
n/=i;
}
}
}
if(n>1)
v.push_back(n);
long long sum=0;
long long cnt;
long long lcm;
for(long long i=1;i<(1<<v.size());i++)//用二进制来1,0来表示第几个素因子是否被用到,如m=3,三个因子是2,3,5,则i=3时二进制是011,表示第2、3个因子被用到
{
cnt=0;
lcm=1;
for(long long j=0;j<v.size();j++)
{
if(i&(1<<j)) //判断第几个因子目前被用到
{
lcm*=v[j];
cnt++;
}
}
if(cnt%2==0)
sum-=x/lcm;
else
sum+=x/lcm;
}
return x-sum;
}
int main()
{
long long t;
cin>>t;
long long cas=0;
while(t--){
scanf("%I64d%I64d%I64d",&a,&b,&n);
printf("Case #%I64d: %I64d\n",++cas,solve(b,n)-solve(a-1,n));
}
return 0;
}
How many integers can you find
Time Limit: 12000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4298 Accepted Submission(s): 1233
Problem Description
Now you get a number N, and a M-integers set, you should find out how many integers which are small than N, that they can divided exactly by any integers in the set. For example, N=12, and M-integer set is {2,3}, so there is another set {2,3,4,6,8,9,10}, all the integers of the set can be divided exactly by 2 or 3. As a result, you just output the number 7.
Input
There are a lot of cases. For each case, the first line contains two integers N and M. The follow line contains the M integers, and all of them are different from each other. 0<N<2^31,0<M<=10, and the M integer are non-negative and won’t exceed 20.
Output
For each case, output the number.
Sample Input
12 2 2 3
Sample Output
7
Author
wangye
Source
2008 “Insigma International Cup” Zhejiang Collegiate Programming Contest - Warm Up(4)
题意及思路:
题意及思路:
求在给定区间内,能被给定集合至少一个数整除的数个数
给出n个整数ai和整数r。求在区间[1;r]中,至少能被一个ai整除的数有多少。
解决此题的思路和上题差不多,计算ai所能组成的各种集合(这里将集合中ai的最小公倍数作为除数)在区间中满足的数的个数,然后利用容斥原理实现加减。
此题中实现所有集合的枚举,需要2^n的复杂度,求解lcm需要O(nlogr)的复杂度。
与上题换汤不换药,都属于经典的容斥原理的模型,不过要注意除去元素为0的情况,再进行容斥。#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
const long long maxn=15;
long long n,m;
long long a[maxn];
long long b[maxn];
long long gcd(long long a,long long b)
{
if(b==0)
return a;
else
return gcd(b,a%b);
}
long long lcm(long long a,long long b)
{
return a/gcd(a,b)/b;
}
int main()
{
while(cin>>n>>m)
{
for(int i=0;i<m;i++)
{
cin>>a[i];
}
n--;
int cnt=0;
for(int i=0;i<m;i++)
{
if(a[i]!=0)
{
b[cnt++]=a[i];
}
}
long long res=0;
for(int i=1;i<(1<<cnt);i++)
{
long long num=0;
long long LCM=1;
for(int j=0;j<cnt;j++)
{
if(i&(1<<j))
{
num++;
LCM=LCM/gcd(LCM,a[j])*(a[j]);
}
}
if(num%2==0) res-=n/LCM;
else res+=n/LCM;
}
cout<<res<<endl;
}
return 0;
}
坑还得慢慢补,http://www.haogongju.net/art/1724838这个地方的文章写得很好,我就是照着这个慢慢看的,容斥原理貌似是莫比乌斯反演的一个特例?。。。也许广州赛区不会考到= =但是以后应该还是会碰到的,重在思维,可惜不会DFS,好忧桑。。。