A.
题目:https://nanti.jisuanke.com/t/38220
题意:求前5个因子和等于它本身的数(不算自身)
线性筛
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 4e6 + 100;
int prime[N], f[N], fu[N], tot;
bool is_prime[N];
void init() {
memset(is_prime, true , sizeof(is_prime));
for (int i = 2; i < N; i++) {
if (is_prime[i]) {
prime[tot++] = i;
f[i] = 1 + i;
fu[i] = i;
}
for (int j = 0; j < tot && i * prime[j] < N; j++) {
is_prime[i * prime[j]] = false;
if (i % prime[j] == 0) {
fu[i * prime[j]] = fu[i] * prime[j];
if (fu[i] == i) {
f[i * prime[j]] = f[i] + i * prime[j];
}else {
f[i * prime[j]] = f[i / fu[i]] * f[fu[i] * prime[j]];
}
break;
}else {
fu[i * prime[j]] = prime[j];
f[i * prime[j]] = f[i] * f[prime[j]];
}
}
if (f[i] == i * 2)
printf("%d\n", i);
}
}
int main() {
puts("6");
puts("28");
puts("496");
puts("8128");
puts("33550336");
return 0;
}
C.
题目:https://nanti.jisuanke.com/t/38222
题意:f(x)是斐波那契数的第x项,g(x)=f(f(x)),对于给定的n,将其表示成若干个g数的和,要求字典序最小,n<10^100000
矩阵快速幂求一下f(x),预处理前29项g(x)。
可以发现g(x)的增长速度非常快,其实在第29项就已经超出10^100000,由于后面的项差过大,所以方法基本唯一,所以就把贪心选一下,然后前几项在特判一下取个最小字典序就ok了。
import java.io.*;
import java.math.*;
import java.util.*;
public class Main
{
static int maxn = 29;
static BigInteger []w = new BigInteger[maxn];
static int []v = new int[maxn];
public static BigInteger f(BigInteger n){
n = n.subtract(BigInteger.ONE);
BigInteger [][]a = new BigInteger[2][2];
BigInteger [][]b = new BigInteger[2][2];
BigInteger [][]c = new BigInteger[2][2];
for(int i = 0; i < 2; i++) for(int j = 0; j < 2; j++) a[i][j] = BigInteger.ZERO;
a[0][0] = a[1][0] = a[0][1] = BigInteger.ONE;
for(int i = 0; i < 2; i++) for(int j = 0; j < 2; j++) b[i][j] = BigInteger.ZERO;
for(int i = 0; i < 2; i++) b[i][i] = BigInteger.ONE;
while(n.compareTo(BigInteger.ZERO) > 0){
if(n.mod(new BigInteger("2")).equals(BigInteger.ONE)){
for(int i = 0; i < 2; i++){
for(int j = 0; j < 2; j++){
c[i][j] = BigInteger.ZERO;
for(int k = 0; k < 2; k++){
c[i][j] = c[i][j].add(b[i][k].multiply(a[k][j]));
}
}
}
for(int i = 0; i < 2; i++){
for(int j = 0; j < 2; j++){
b[i][j] = c[i][j];
}
}
}
for(int i = 0; i < 2; i++){
for(int j = 0; j < 2; j++){
c[i][j] = BigInteger.ZERO;
for(int k = 0; k < 2; k++){
c[i][j] = c[i][j].add(a[i][k].multiply(a[k][j]));
}
}
}
for(int i = 0; i < 2; i++){
for(int j = 0; j < 2; j++){
a[i][j] = c[i][j];
}
}
n = n.divide(new BigInteger("2"));
}
//System.out.println("len " + b[0][0].toString().length());
return b[0][0];
}
public static void main(String[] args)
{
Scanner cin = new Scanner (System.in);
for(int i = 1; i < maxn; i++){
w[i] = f(f(BigInteger.valueOf(i)));
}
// System.out.println(w[6] + " " + w[7]);
int T = cin.nextInt();
while(T > 0){
T--;
BigInteger n = cin.nextBigInteger();
int tot = 0;
for(int i = maxn - 1; i > 0; i--){
if(n.equals(new BigInteger("5")) && i >= 4){
v[tot++] = 4;
v[tot++] = 3;
v[tot++] = 2;
v[tot++] = 1;
n = BigInteger.ZERO;
break;
}
if(n.equals(new BigInteger("4")) && i >= 4){
v[tot++] = 4;
v[tot++] = 2;
v[tot++] = 1;
n = BigInteger.ZERO;
break;
}
if(n.equals(new BigInteger("3")) && i >= 3){
v[tot++] = 3;
v[tot++] = 2;
v[tot++] = 1;
n = BigInteger.ZERO;
break;
}
if(n.equals(new BigInteger("2")) && i >= 2){
v[tot++] = 2;
v[tot++] = 1;
n = BigInteger.ZERO;
break;
}
if(n.equals(new BigInteger("1")) && i >= 1){
v[tot++] = 1;
n = BigInteger.ZERO;
break;
}
if(n.compareTo(w[i]) >= 0){
v[tot++] = i;
n = n.subtract(w[i]);
}
}
if(!n.equals(BigInteger.ZERO)) System.out.println(-1);
else{
for(int i = tot - 1; i >= 0; i--) System.out.printf("%d%c", v[i], i == 0 ? '\n