第1题:
根据整数模 的性质处理输入(先乘10再模和先模再乘得到的数同余),(bx,a)的关系可写成(bx,1)和(a,a);代码如下:
#include <iostream>
using namespace std;
#define MOD 19260817
inline int input();
long long quickPow(int x, int y);
int main() {
long long a, b;
a = input();
b = input();
if (b) {
printf("%lld\n", (a * quickPow(b, MOD - 2)) % MOD);
}
else {
puts("Angry!");
}
return 0;
}
inline int input() {
char ch;
int num = 0;
ch = getchar();
while (!isdigit(ch)) {
ch = getchar();
}
while (isdigit(ch) ){
num = (num << 3) + (num << 1) + ch - '0';
num %= MOD;
ch = getchar();
}
return num;
}
long long quickPow(int x, int y) {
long long num =1;
long long ab = x%MOD;
while (y > 0) {
if (y & 1) {
num = (num * ab) % MOD;
}
ab = (ab * ab) % MOD;
y >>= 1;
}
return num;
}
第2题:
相邻数互质,相邻够小了,再大点就会把它包含掉,所以不用考虑比它大的区间,有特殊情况1和1,代码如下:
#include <iostream>
using namespace std;
int main() {
int t;
scanf("%d", &t);
for (int i = 0; i < t; i++) {
int l, r;
scanf("%d%d", &l, &r);
if (l == 1) {
if (r == 1)printf("1\n");
else {
printf("%d\n", r - l);
}
}
else {
printf("%d\n", r - l);
}
}
return 0;
}
第3题:
r可能非常大,直接筛会爆,考虑到合数能分解成两个非1非本身的数,故筛sqrt(r) ,具体代码如下:
#include <iostream>
#include<cmath>
#include<vector>
using namespace std;
vector<int>prime;
vector<int>sign;
void getprime(int r);
int getnum(int l, int r);
int main() {
int l, r;
scanf("%d%d", &l, &r);
if (l == 1)l = 2;
getprime(sqrt(r));
printf("%d", getnum(l, r));
return 0;
}
void getprime(int r) {
sign.assign(r + 1, false);
for (int i = 2; i <= r; i++) {
if (!sign[i]) {
prime.push_back(i);
}
for (int p : prime) {
if (p * i > r)break;
sign[p * i] = true;
if (i % p == 0)break;
}
}
}
int getnum(int l, int r) {
int num = 0;
for (int i = l; i <= r; i++) {
int k = 0;
int kk = sqrt(i);
for (int p : prime) {
if (p > kk)break;
if (i % p == 0) {
k = 1;
break;
}
}
if (!k)num++;
}
return num;
}
第4题:
就是看最大公约数和最小公约数分解的素数种类及对应个数,然后讨论就可以了,代码如下:
#include <iostream>
#include<cmath>
#include<vector>
using namespace std;
vector<int>prime;
vector<int>sign;
void getprime(int r);
int main() {
int l, r;
int sum = 1;
scanf("%d%d", &l, &r);
if (l == r) {
printf("%d", 1);
return 0;
}
if (l == 1) {
printf("2");
return 0;
}
getprime(r);
for (int p : prime) {
if (r % p == 0) {
int num = 0;
while (r % p == 0) {
num++;
r /= p;
}
while (l % p == 0) {
num--;
l /= p;
}
if (num < 0) {
printf("0");
return 0;
}
sum*=(num==0?1:2);
}
if (l % p == 0) {
printf("0");
return 0;
}
}
printf("%d",sum);
return 0;
}
void getprime(int r) {
sign.assign(r + 1, false);
for (int i = 2; i <= r; i++) {
if (!sign[i]) {
prime.push_back(i);
}
for (int p : prime) {
if (p * i > r)break;
sign[p * i] = true;
if (i % p == 0)break;
}
}
}
第5题:
这个直接把所有可能的lcm给统计出来 ,然后找到最大的lcm,这里要注意的是,在求每一个lcm时,不必去一定要最小公倍,只要是公倍就行,即弱化条件,因为在后续找最大lcm的过程中,不会选到不是最小公倍的。具体代码如下:
#include <iostream>
using namespace std;
int arr[1000000][2];
int f[1000001] = {0};
int g[1000001] = { 0 };
int main() {
int n, m;
scanf("%d%d", &n, &m);
int a;
int k = 0;
for (int i = 0; i < n; i++) {
scanf("%d", &a);
if (a <= m) {
arr[k][0] = a;
arr[k][1] = i + 1;
g[a]++;
k++;
}
}
if (k == 0) {
printf("1 0\n");
return 0;
}
for (int i = 0; i < k; i++) {
if (g[arr[i][0]]) {
int sa = m / arr[i][0];
for (int j = 1; j <= sa; j++) {
f[arr[i][0] * j]+=g[arr[i][0]];
}
g[arr[i][0]] = 0;
}
}
int max = 0;
int lcm = 0;
for (int i = 1; i <= m; i++) {
if (max < f[i]) {
max = f[i];
lcm = i;
}
}
cout << lcm << ' ' << max<<endl;
for (int i = 0; i < k; i++) {
if (lcm % arr[i][0] == 0) {
printf("%d ", arr[i][1]);
}
}
return 0;
}
第6题:
数论问题,质数是一个关键,质数可以由其他数转化过来吗?思考一下,是不可以的,所以如果数组里有质数,如果所求值存在,必为该质数,所以不能有两个质数。而且,2能够转换成任意合数。所以只剩只有一个质数的情况了,分奇偶讨论并用类似证明2可以转化成任意合数的方法来证就可以了。具体代码如下:
#include <iostream>
#include <vector>
using namespace std;
#define N 400005
int factor[N + 1];
void isPrime() {
vector<int> sg(N + 1, 0), prime;
for (int i = 2; i <= N; i++) {
if (!sg[i]) {
prime.push_back(i);
factor[i] = i;
}
for (int j = 0; prime[j] <= N / i; j++) {
sg[prime[j] * i] = true;
factor[prime[j] * i] = prime[j];
if (i % prime[j] == 0) break;
}
}
}
int main() {
isPrime();
int t;
cin >> t;
for(int hh=0;hh<t;hh++){
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
int ans = 0;
for (int x : a) {
if (factor[x] == x) {
if (ans) {
ans = -1;
break;
}
else ans = x;
}
}
if (ans == -1) {
cout << ans << endl;
}
else if (!ans||ans==2) {
cout << '2' << endl;
}
else {
int ko = 0;
for (int kk : a) {
if (kk == ans)continue;
if (kk % 2 == 0 && kk < 2 * ans)ko = 1;
if (kk % 2 == 1 && kk - factor[kk] < 2 * ans)ko = 1;
if (ko)break;
}
if (ko)ans = -1;
cout << ans << endl;
}
}
return 0;
}