2018-7-12 ACM 专项刷题 简单数论

1. Gcd & Lcm:

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
LL a, b;

LL gcd(LL x, LL y) {
	if(x % y == 0) return y;
	else return gcd(y, x % y);
}

LL lcm(LL x, LL y) { return x * y / gcd(x, y); }

int main() {
	while(~scanf("%I64d %I64d", &a, &b)) {
		printf("%I64d %I64d\n", gcd(a, b), lcm(a, b));
	}
}

2. 哥德巴赫猜想:

强哥德巴赫猜想(关于偶数的哥德巴赫猜想):任一大于2的偶数都可写成两个素数之和

弱哥德巴赫猜想(关于奇数的哥德巴赫猜想):任一大于7的奇数都可写成三个素数之和

对应题目:Codeforces - 735D

题解:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
int n, ans;

bool chk(int n) {
	if(n < 2) return 0;
	for(int i = 2; i <= sqrt(n); i++) {
		if(!(n % i)) return 0;
	}
	return 1;
}

int main() {
	cin >> n;
	if(chk(n)) ans = 1;
	else if(!(n & 1)) ans = 2;
	else if(chk(n - 2)) ans = 2;
	else ans = 3;
	cout << ans << endl;
}

3. 快速幂:

快速幂a^b模板:

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const LL Mod = 1e9 + 7;
int a, b;

LL qwe(LL x, LL y) {
	LL t = 1;
	while(y) {
		if(y & 1) t = t * x % Mod;
		y /= 2;
		x = x * x % Mod;
	}
	return t;
}

int main() {
	scanf("%I64d %I64d", &a, &b);
	printf("%I64d\n", qwe(a, b));
	return 0;
}

通常应用为,快速求幂后取模,即求快速幂结果的后若干位。

对应题目:HDU - 2035 、HDU - 1061

HDU - 2035 题解: 

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll Mod = 1e9;

ll qwe(ll x, ll y) {
	ll t = 1;
	while(y) {
		if(y & 1) t = t * x % Mod;
		y >>= 1;
		x = x * x % Mod;
	}
	return t;
}

int main() {
	ll a, b;
	while(cin >> a >> b && a && b) {
		printf("%I64d\n", (ll)qwe(a, b) % 1000);
	}
	return 0;
}

HDU - 1061 题解:

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll Mod = 1e9;
int cas;
int n;

ll qwe(ll x, ll y) {
	ll t = 1;
	while(y) {
		if(y & 1) t = t * x % Mod;
		y >>= 1;
		x = x * x % Mod;
	}
	return t;
}

int main() {
	cin >> cas;
	while(cas--) {
		cin >> n;
		ll ans = (ll)qwe(n, n) % 10;
		cout << ans << endl;
	}
}

4. 二分查找:

二分模板 (给出一个长度为n的升序序列,q个查询区间,问每个区间内覆盖数列元素的个数 - LightOJ - 1088):

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MaxN = 1e5;
int T;
int n, m;
int a[MaxN + 10];
int p[MaxN];
int solve(int x, int y) {
	int l = 1, r = n, ans1 = n + 1, ans2 = 0;
	while(l <= r) {
		int mid = (l + r) >> 1; // mid = (l + r) / 2 等价于 mid = (l + r) >> 1.
		if(x <= a[mid]) r = mid - 1, ans1 = mid;
		else l = mid + 1;
	}
	l = 1, r = n;
	while(l <= r) {
		int mid = (l + r) / 2;
		if(y >= a[mid]) l = mid + 1, ans2 = mid;
		else r = mid - 1;
	}
	return ans2 - ans1 + 1;
}

int main() {
	int t = 0;
	scanf("%d", &T);
	while(T--) {
		int x, y;
		scanf("%d %d", &n, &m);
		for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
		for(int i = 1; i <= m; i++) {
			scanf("%d %d", &x, &y);
			p[i] = solve(x, y);
		}
		printf("Case %d:\n", ++t);
		for(int i = 1; i <= m; i++) printf("%d\n", p[i]);
	}
	return 0;
}

对应题目:Codeforces - 706B

题解:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MaxN = 1e5;
int n, m;
int a[MaxN + 10];

int solve(int x, int y) {
	int l = 1, r = n, ans1 = n + 1, ans2 = 0;
	while(l <= r) {
		int mid = (l + r) >> 1;
		if(x <= a[mid]) r = mid - 1, ans1 = mid;
		else l = mid + 1;
	}
	l = 1, r = n;
	while(l <= r) {
		int mid = (l + r) >> 1;
		if(y >= a[mid]) l = mid + 1, ans2 = mid;
		else r = mid - 1;
	}
	return ans2 - ans1 + 1;
}

int main() {
	int q;
	scanf("%d", &n);
	for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
	sort(a + 1, a + n + 1);
	scanf("%d", &m);
	while(m--) {
		scanf("%d", &q);
		printf("%d\n", solve(a[1], q));
	}
	return 0;
}

5. O(n)筛素数:

模板:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxx = 1e5 + 7;
int pri[maxx];
bool vis[maxx];
int tot;

void Prime(int n) {
	for(int i = 2; i <= n; i++) {
		if(!vis[i]) pri[++tot] = i;
		for(int j = 1; j <= tot && i * pri[j] <= maxx; j++) {
			vis[i * pri[j]] = 1;
			if(!(i % pri[j])) break;
		}
	}
}

int main() {
	int n;
	cin >> n;
	Prime(n);
	for(int i = 1; i <= tot; i++) cout << pri[i] << endl;
}

猜你喜欢

转载自blog.csdn.net/ericgipsy/article/details/81023381