数论题集
A - Happy 2006
POJ - 2773 (欧拉函数)
题意:求第k个与n互质的数(k大于n)
题解:gcd(a,b) = gcd(b,a % b) = gcd(b, a + b * n)可见,与b的gcd == 1的数是可以轮回的,那么这就可以先预先处理出小于n的数厘米的与n互质的,然后开始判断这是在第几个周期里面的第几个数
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<cmath> #include<stack> #include<cstdlib> #include<queue> #include<set> #include<string.h> #include<vector> #include<deque> #include<map> using namespace std; #define INF 0x3f3f3f3f3f3f3f3f #define inf 0x3f3f3f3f #define eps 1e-4 #define bug printf("*********\n") #define debug(x) cout<<#x"=["<<x<<"]" <<endl #define Mod(a,b) a<b?a:a%b+b typedef long long LL; typedef long long ll; const int maxn = 1e6 + 5; int euler[maxn + 10]; void phi() { for (int i = 1; i <= maxn; i++) euler[i] = i; for (int i = 2; i <= maxn; i += 2) euler[i] = i / 2; for (int i = 3; i <= maxn; i++) { if (euler[i] == i) { for(int j = i; j <= maxn; j += i) euler[j] = euler[j] / i * (i - 1); } } } int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); } int main() { int n, k; phi(); while (~scanf("%d %d",&n, &k)) { int t = k / euler[n]; //第几个周期 int p = k % euler[n]; //该个周期的第几个 if (p == 0) { t--; p = euler[n]; } int i; for (i = 1; i <= n; i++) { if (gcd(i, n) == 1) p--; if (p == 0) break; } printf("%lld\n",i + (LL) t * n); } }
B - Prime Distance
POJ - 2689 (素数筛)
题意:给你一个L,U(1<=L< U<=2,147,483,647),The difference between L and U will not exceed 1,000,000,要求在L,U中找一对相邻的素数要求其差值(大减小)最小和最大,并输出
题解:由于L,U过于庞大不可以直接打表,便可采用删去和数的方法,显然L和U如果是和数的话必定还有1e5以下的因子,那就筛取1e5以内的质数,并在L,U中将其倍数删去
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<cmath> #include<stack> #include<cstdlib> #include<queue> #include<set> #include<string.h> #include<vector> #include<deque> #include<map> using namespace std; #define INF 0x3f3f3f3f3f3f3f3f #define inf 0x3f3f3f3f #define eps 1e-4 #define bug printf("*********\n") #define debug(x) cout<<#x"=["<<x<<"]" <<endl #define Mod(a,b) a<b?a:a%b+b typedef long long LL; typedef long long ll; const int maxn = 1e5 + 5; int prime[maxn + 1]; void getPrime() { memset(prime,0,sizeof prime); for (int i = 2; i <= maxn; i++) { if(!prime[i]) prime[++prime[0]] = i; for (int j = 1; j <= prime[0] && prime[j] <= maxn / i; j++) { prime[prime[j] * i] = 1; if (i % prime[j] == 0) break; } } } int vis[maxn * 10]; int main() { getPrime(); // cout << prime[0] << endl; int l, r; while (~scanf("%d %d", &l, &r)) { memset(vis, 0, sizeof vis); if (l == 1) l++; for (int i = 1; i < prime[0]; i++) { int a = (l - 1) / prime[i] + 1; int b = r / prime[i]; for (int j = a; j <= b; j++) if (j > 1) vis[j * prime[i] - l] = 1; } int p = -1, max_ans = -1, min_ans = inf; int x1, x2, y1, y2; for (int i = 0; i <= r - l; i++) { if (vis[i] == 0) { if (p == -1) { p = i; continue; } if (max_ans < i - p) { max_ans = i - p; x1 = p + l; y1 = i + l; } if (min_ans > i - p) { min_ans = i - p; x2 = p + l; y2 = i + l; } p = i; } } if (max_ans == -1)cout << "There are no adjacent primes." << endl; else cout << x2 << "," << y2 << " are closest, " << x1 << "," << y1 << " are most distant." << endl; } }

浙公网安备 33010602011771号