HDU4135 HDU2841 HDU1695 求[1,m]中与n互素的数的个数
求n的質(zhì)因子
模板:求1-m之間與n互素的數(shù)的個(gè)數(shù)
vector<ll>p; //返回1-m中與n互素的數(shù)的個(gè)數(shù) ll cal(ll n,ll m) {p.clear();for(int i=2;i*i<=n;i++){if(n%i==0){p.push_back(i);while(n%i==0) n/=i;}}if(n>1) p.push_back(n);//求n的素因子int num=p.size();//素因子的個(gè)數(shù)int maxs=1<<num;//從中選出一些質(zhì)因子,就是生成子集,子集最多的個(gè)數(shù)ll s=0;//1到m中與n不互素的數(shù)的個(gè)數(shù)//枚舉子集,不能有空集,所以從1開始for(ll i=1;i<maxs;i++){//從1枚舉到(2^素因子個(gè)數(shù))ll cnt=0;ll mul=1;for(ll j=0;j<num;j++){//枚舉每個(gè)素因子if(i&(1<<j)){//有第i個(gè)因子cnt++;//計(jì)數(shù)mul*=p[j];//乘上這個(gè)質(zhì)因子}}//容斥原理if(cnt&1) //選取個(gè)數(shù)為奇數(shù),加s+=m/mul;else //選取個(gè)數(shù)為偶數(shù),減s-=m/mul;}return m-s;//返回1-m中與n互素的數(shù)的個(gè)數(shù) }HDU4135
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.
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 5Sample Output
Case #1: 5 Case #2: 10Hint
In the first test case, the five integers in range [1,10] which are relatively prime to 2 are {1,3,5,7,9}.? ? ? ?
?題意:
求區(qū)間[a,b]中與n互素的數(shù)字個(gè)數(shù)
分析:
考慮一下逆向問題:求1-m之間與n不互素的個(gè)數(shù),不互素則一定至少有一個(gè)素因子。這樣就可以枚舉n的素因子,然后計(jì)算[a,b]區(qū)間有多少個(gè)n的素因子,其實(shí)這并不好算。
考慮[1,a-1]和[1,b]兩個(gè)區(qū)間與n互素的個(gè)數(shù),答案就是二者之差。互素的個(gè)數(shù)等于總數(shù)減去不互素的個(gè)數(shù),然后問題轉(zhuǎn)換為容斥原理經(jīng)典問題:求1-m中與n互素的數(shù)的個(gè)數(shù)
如果1-m中某個(gè)數(shù)與n不互素,那么一定可以被n的某個(gè)因子整除,所以先枚舉n的所有素因子。
舉個(gè)例子,n=12,m=8,12的素因子是2,3,1-8中有幾個(gè)是2的倍數(shù)呢?num2=8/2=4;? 1-8中有幾個(gè)是3的倍數(shù)呢?num3=8/3=2,那么1-8之間與12互素的個(gè)數(shù)是2+4=6個(gè)數(shù)字嗎?1-8之間與12不互素的是2,3,4,6,8,共5個(gè)數(shù)字,這是因?yàn)橥瑸?和3的倍數(shù)的6被計(jì)算了兩次,所以要再減去一次num6=8/6,結(jié)果是 8/2+8/3-8/(2*3).
結(jié)論:如果是奇數(shù)個(gè)組合,那么符號(hào)是加;如果是偶數(shù)個(gè)組合,那么符號(hào)是減;
AC code
#include<bits/stdc++.h> using namespace std; typedef long long ll;vector<ll>p; //返回1-m中與n互素的數(shù)的個(gè)數(shù) ll fun(ll n,ll m) {p.clear();for(int i=2;i*i<=n;i++){if(n%i==0){p.push_back(i);while(n%i==0) n/=i;}}if(n>1) p.push_back(n);//求n的素因子int num=p.size();//素因子的個(gè)數(shù)ll s=0;//1到m中與n不互素的數(shù)的個(gè)數(shù)for(ll i=1;i<(1<<num);i++){//從1枚舉到(2^素因子個(gè)數(shù))ll cnt=0;ll mul=1;for(ll j=0;j<num;j++){//枚舉每個(gè)素因子if(i&(1<<j)){//若對(duì)應(yīng)位置為1,那么計(jì)入cnt++;mul*=p[j];}}//容斥原理if(cnt&1) //選取個(gè)數(shù)為奇數(shù),加s+=m/mul;else //選取個(gè)數(shù)為偶數(shù),減s-=m/mul;}return m-s;//返回1-m中與n互素的數(shù)的個(gè)數(shù) }int main() {int T,ca=0;scanf("%d",&T);while(T--){ll n,a,b;scanf("%lld%lld%lld",&a,&b,&n);ll ans=fun(n,b)-fun(n,a-1);printf("Case #%d: %lld\n",++ca,ans);}return 0; }HDU2841
There are many trees forming a m * n grid, the grid starts from (1,1). Farmer Sherlock is standing at (0,0) point. He wonders how many trees he can see.?
If two trees and Sherlock are in one line, Farmer Sherlock can only see the tree nearest to him.
Input
The first line contains one integer t, represents the number of test cases. Then there are multiple test cases. For each test case there is one line containing two integers m and n(1 ≤ m, n ≤ 100000)
Output
For each test case output one line represents the number of trees Farmer Sherlock can see.
Sample Input
2 1 1 2 3Sample Output
1 5?題意:
給一個(gè)n*m的矩陣,左下角為(1,1),右上角為(n,m),問從(0,0)點(diǎn)可以看到多少個(gè)點(diǎn)。
分析:
如果gcd(x,y)=g,g!=1,那么一定被(x/g,y/g)的點(diǎn)擋住
兩個(gè)數(shù)字(x,y)如果兩數(shù)互質(zhì),則可以被看到;如果不互質(zhì),則看不到,所以我們就是要找出所有的互質(zhì)二元組(x,y)
我們可以固定一個(gè)數(shù)字,用一個(gè)數(shù)來循環(huán)。例如矩陣為n*m,我們固定m,用n來循環(huán),即1與[1,m]里面多少個(gè)數(shù)互質(zhì),2與[1,m]里面多少個(gè)數(shù)互質(zhì),3與[1,m]里面多少個(gè)數(shù)互質(zhì)……n與[1,m]里面多少個(gè)數(shù)互質(zhì),把這些結(jié)果全部累加起來即可
所以問題的最后變?yōu)榱?#xff0c;給定一個(gè)數(shù)字x,找出它和1到y(tǒng)里面有多少個(gè)數(shù)互質(zhì)
#include<bits/stdc++.h> using namespace std; typedef long long ll;vector<ll>p; //返回1-m中與n互素的數(shù)的個(gè)數(shù) ll fun(ll n,ll m) {p.clear();for(int i=2;i*i<=n;i++){if(n%i==0){p.push_back(i);while(n%i==0) n/=i;}}if(n>1) p.push_back(n);//求n的素因子int num=p.size();//素因子的個(gè)數(shù)ll s=0;//1到m中與n不互素的數(shù)的個(gè)數(shù)for(ll i=1;i<(1<<num);i++){//從1枚舉到(2^素因子個(gè)數(shù))ll cnt=0;ll mul=1;for(ll j=0;j<num;j++){//枚舉每個(gè)素因子if(i&(1<<j)){//若對(duì)應(yīng)位置為1,那么計(jì)入cnt++;mul*=p[j];}}//容斥原理if(cnt&1) //選取個(gè)數(shù)為奇數(shù),加s+=m/mul;else //選取個(gè)數(shù)為偶數(shù),減s-=m/mul;}return m-s;//返回1-m中與n互素的數(shù)的個(gè)數(shù) } int main() {int T,ca=0;scanf("%d",&T);while(T--){ll a,b;scanf("%lld%lld",&a,&b);ll ans=0;for(int i=1;i<=a;i++){ans+=fun(i,b);}printf("%lld\n",ans);}return 0; }HDU1695?
Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD(x, y) = k. GCD(x, y) means the greatest common divisor of x and y. Since the number of choices may be very large, you're only required to output the total number of different number pairs.?
Please notice that, (x=5, y=7) and (x=7, y=5) are considered to be the same.?
Yoiu can assume that a = c = 1 in all test cases.?
Input
The input consists of several test cases. The first line of the input is the number of the cases. There are no more than 3,000 cases.?
Each case contains five integers: a, b, c, d, k, 0 < a <= b <= 100,000, 0 < c <= d <= 100,000, 0 <= k <= 100,000, as described above.?
Output
For each test case, print the number of choices. Use the format in the example.?
Sample Input
2 1 3 1 5 1 1 11014 1 14409 9Sample Output
Case 1: 9 Case 2: 736427Hint
For the first sample input, all the 9 pairs of numbers are (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 5), (3, 4), (3, 5).題意:? ,求gcd(x,y)=k的(x,y)的個(gè)數(shù)
分析:顯然,等價(jià)于求b,d同時(shí)除以k,求gcd(x,y)=1的個(gè)數(shù),因?yàn)?1,3)和(3,1)是一種情況,所以要限制(x<y)
#include<bits/stdc++.h> using namespace std; typedef long long ll; vector<ll>p; ll cal(ll n,ll m) {p.clear();for(int i=2;i*i<=n;i++){if(n%i==0){p.push_back(i);while(n%i==0) n/=i;}}if(n>1) p.push_back(n);int num=p.size();ll maxs=1<<num;ll s=0;for(ll i=1;i<maxs;i++){ll cnt=0;ll mul=1;for(ll j=0;j<num;j++){if(i&(1<<j)){cnt++;mul*=p[j];}}if(cnt&1) s+=m/mul;else s-=m/mul;}return m-s; } int main() {int T,ca=0;scanf("%d",&T);while(T--){ll a,b,c,d,k;scanf("%lld%lld%lld%lld%lld",&a,&b,&c,&d,&k);if(!k){printf("Case %d: 0\n",++ca);continue;}b/=k;d/=k;if(b>d) swap(d,b);ll ans=0;for(ll i=1;i<=d;i++){ll k=min(i,b);//求區(qū)間[1,k]內(nèi)與i互質(zhì)的個(gè)數(shù)ans+=cal(i,k);}printf("Case %d: %lld\n",++ca,ans);}return 0; }總結(jié)
以上是生活随笔為你收集整理的HDU4135 HDU2841 HDU1695 求[1,m]中与n互素的数的个数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 快速乘法模板
- 下一篇: Catalan Numbers 卡特兰数