QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#876550#9309. GraphHygebraWA 43ms70712kbC++143.2kb2025-01-30 23:50:042025-01-30 23:50:05

Judging History

This is the latest submission verdict.

  • [2025-01-30 23:50:05]
  • Judged
  • Verdict: WA
  • Time: 43ms
  • Memory: 70712kb
  • [2025-01-30 23:50:04]
  • Submitted

answer

//
// Created by Yang Hang on 2025/1/29.
//
#include <cstdio>
#include <cmath>
#include "vector"
using namespace std;
const int mod=998244353;
const int N=4000005;
int fact[N],ifact[N];
long long n;
inline int binom(int n,int m) {
    if (m>n || n<0 || m<0) return 0;
    return 1ll*fact[n]*ifact[m]%mod*ifact[n-m]%mod;
}
long long ksm(long long a,long long x) {
    long long s=1;
    while (x) {
        if (x&1) s=1ll*s*a%mod;
        a=1ll*a*a%mod;x>>=1;
    }
    return s;
}
const int INF = 2e9;
const long long INFLL = 4e18;
const int small_lim = 1e6+1;
const int big_lim = 1e3+1;
long long primes_till_i[small_lim];
long long primes_till_bigger_i[big_lim];
vector<long long> sieved_primes[small_lim];
vector<long long> sieved_primes_big[big_lim];
vector<long long> prime;
vector<int> lpf(small_lim);
void get(){
    long long pw;
    for(int i = 2; i < small_lim; i++){
        if(! lpf[i]){
            prime.push_back(i);
            lpf[i] = i;
        }
        for(int j : prime){
            if((j > lpf[i]) || (j*i >= small_lim)) break;
            lpf[j*i] = j;
        }
    }
    for(int i = 2; i < small_lim; i++){
        primes_till_i[i] = primes_till_i[i-1] + (lpf[i] == i);
    }
}
long long count_primes(long long x, int ind){
    if(ind < 0) return x - 1;
    if(1ll*prime[ind]*prime[ind] > x){
        if(x < small_lim) return primes_till_i[x];
        if(primes_till_bigger_i[n / x]) return primes_till_bigger_i[n / x];
        int l = -1, r = ind;
        while(r-l > 1){
            int mid = (l+r)>>1;
            if(1ll*prime[mid]*prime[mid] > x) r = mid;
            else l = mid;
        }
        return primes_till_bigger_i[n / x] = count_primes(x, l);
    }
    int sz;
    if(x < small_lim) sz = sieved_primes[x].size();
    else sz = sieved_primes_big[n / x].size();
    long long ans;
    if(sz <= ind){
        ans = count_primes(x, ind - 1);
        ans -= count_primes(x / prime[ind], ind - 1);
        ans += ind;
        if(x < small_lim) sieved_primes[x].push_back(ans);
        else sieved_primes_big[n / x].push_back(ans);
    }
    if(x < small_lim) return sieved_primes[x][ind];
    else return sieved_primes_big[n / x][ind];
}
long long count_primes(long long x){
    //printf("x = %lld\n",prime.size()-1);
    if(x < small_lim) return primes_till_i[x];
    if(primes_till_bigger_i[n/x]) return primes_till_bigger_i[n/x];
    //puts("c");
    return count_primes(x,prime.size()-1);
}
int main()
{
    get();
/*    for (int i=0;i<100;++i)
        if (count_primes(i) - count_primes(i-1))
            printf("%d ",i);puts("pr");*/
    fact[0]=1;
    for (int i=1;i<N;++i)
        fact[i]=1ll*fact[i-1]*i%mod;
    ifact[N-1]=ksm(fact[N-1],mod-2);
    for (int i=N-2;i>=0;--i)
        ifact[i]=(i+1ll)*ifact[i+1]%mod;
    scanf("%lld",&n);
    long long res = 1;
    for (long long l = 1, r, o,tmp; l<=n; l = r + 1) {
        o = n/l;
        r = n/o;
        tmp = count_primes(o)- count_primes(o/2);
        if (o-tmp-1ll<1ll) {
            continue;
        }
        //printf("[%lld - %lld] [n/d] = %lld, tmp = %lld\n",l,r,o,tmp);
        res = (res * (o - tmp - 1ll) %mod * ksm(o%mod, tmp)) % mod;
    }
    printf("%lld\n",res);
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 43ms
memory: 70712kb

input:

4

output:

8

result:

ok answer is '8'

Test #2:

score: 0
Accepted
time: 42ms
memory: 70708kb

input:

2

output:

1

result:

ok answer is '1'

Test #3:

score: -100
Wrong Answer
time: 41ms
memory: 70580kb

input:

123

output:

648894067

result:

wrong answer expected '671840470', found '648894067'