結果
| 問題 |
No.1322 Totient Bound
|
| コンテスト | |
| ユーザー |
chocorusk
|
| 提出日時 | 2020-12-13 20:03:46 |
| 言語 | Java (openjdk 23) |
| 結果 |
AC
|
| 実行時間 | 1,262 ms / 5,000 ms |
| コード長 | 2,456 bytes |
| コンパイル時間 | 2,168 ms |
| コンパイル使用メモリ | 77,408 KB |
| 実行使用メモリ | 92,052 KB |
| 最終ジャッジ日時 | 2024-09-19 23:51:51 |
| 合計ジャッジ時間 | 26,664 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 36 |
ソースコード
import java.util.Scanner;
public class Main {
public static final int MAX=1000000;
public static boolean[] isprime=new boolean[MAX];
public static void sieve() {
for(int i=2; i<MAX; i++) isprime[i]=true;
for(int i=2; i<MAX; i++) {
if(isprime[i]) {
for(int j=(i<<1); j<MAX; j+=i) {
isprime[j]=false;
}
}
}
}
public static long n, sq;
public static int isq;
public static long[] p=new long[MAX];
public static long[] divs=new long[MAX];
public static long[] pc=new long[MAX];
public static int m;
public static void calc() {
while((sq+1)*(sq+1)<=n) sq++;
for(long i=1; i<=sq; i++) divs[m++]=i;
for(long i=sq; i>=1; i--) if(n/i>sq) divs[m++]=n/i;
int k=0;
isq=-1;
for(int i=2; i<MAX; i++) {
if(isprime[i]) {
p[k]=i;
if(p[k]>sq && isq==-1) isq=k;
k++;
}
}
}
public static int idx(long x) {
if(x<=sq) return (int)(x-1);
else return m-(int)(n/x);
}
public static void primecount(){
long[] dp=new long[m];
for(int i=0; i<m; i++) dp[i]=divs[i];
int l=0, r=0;
while(r<m && divs[r]<p[0]*p[0]) r++;
for(int i=l; i<r; i++) {
if(divs[i]==1) pc[i]=0;
else if(divs[i]==2) pc[i]=1;
else pc[i]=2;
}
for(int i=1; i<=isq; i++) {
l=r;
while(r<m && divs[r]<p[i]*p[i]) r++;
for(int j=m-1; j>=l; j--) {
long a=dp[j];
if(divs[j]<p[i-1]*p[i-1]) a=pc[j]-(i-1)+1;
int k=idx(divs[j]/p[i-1]);
long b=dp[k];
if(divs[k]<p[i-1]*p[i-1]) b=pc[k]-(i-1)+1;
dp[j]=a-b;
}
for(int j=l; j<r; j++) {
pc[j]=dp[j]-1+i;
}
}
}
public static boolean is_prime(long x) {
if(x<MAX) return isprime[(int)x];
for(long i=2; i*i<=x; i++) {
if(x%i==0) return false;
}
return true;
}
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
n=scanner.nextLong();
sieve();
calc();
primecount();
for(int i=0; i<m; i++) {
if(is_prime(divs[i]+1)) pc[i]++;
}
long[] dp=new long[m];
int l=m-1;
for(int i=(int)isq; i>=0; i--) {
while(l>=0 && divs[l]>=p[i]*(p[i]-1)) l--;
for(int j=m-1; j>=l+1; j--) {
long a=dp[j];
if(divs[j]<p[i+1]-1) a=1;
else if(divs[j]<p[i+1]*(p[i+1]-1)) a=pc[j]-(i+1)+1;
long q=p[i]-1;
while(q<=divs[j]) {
long x=divs[j]/q;
int k=idx(x);
long b=dp[k];
if(x<p[i+1]-1) b=1;
else if(x<p[i+1]*(p[i+1]-1)) b=pc[k]-(i+1)+1;
a+=b;
q*=p[i];
}
dp[j]=a;
}
}
dp[0]=2;
System.out.println(dp[m-1]);
scanner.close();
}
}
chocorusk