結果

問題 No.1781 LCM
ユーザー chocoruskchocorusk
提出日時 2021-12-10 22:44:15
言語 C++17(clang)
(17.0.6 + boost 1.83.0)
結果
AC  
実行時間 2,479 ms / 5,000 ms
コード長 3,106 bytes
コンパイル時間 3,180 ms
コンパイル使用メモリ 164,236 KB
実行使用メモリ 21,144 KB
最終ジャッジ日時 2024-04-27 18:03:00
合計ジャッジ時間 19,773 ms
ジャッジサーバーID
(参考情報)
judge3 / judge4
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 8 ms
6,812 KB
testcase_01 AC 9 ms
6,944 KB
testcase_02 AC 9 ms
6,944 KB
testcase_03 AC 9 ms
6,944 KB
testcase_04 AC 9 ms
6,944 KB
testcase_05 AC 9 ms
6,940 KB
testcase_06 AC 9 ms
6,944 KB
testcase_07 AC 9 ms
6,944 KB
testcase_08 AC 8 ms
6,940 KB
testcase_09 AC 8 ms
6,940 KB
testcase_10 AC 9 ms
6,940 KB
testcase_11 AC 8 ms
6,940 KB
testcase_12 AC 8 ms
6,940 KB
testcase_13 AC 8 ms
6,940 KB
testcase_14 AC 8 ms
6,940 KB
testcase_15 AC 8 ms
6,940 KB
testcase_16 AC 8 ms
6,940 KB
testcase_17 AC 8 ms
6,940 KB
testcase_18 AC 8 ms
6,944 KB
testcase_19 AC 8 ms
6,944 KB
testcase_20 AC 8 ms
6,948 KB
testcase_21 AC 2,479 ms
20,164 KB
testcase_22 AC 2,460 ms
19,152 KB
testcase_23 AC 9 ms
6,944 KB
testcase_24 AC 8 ms
6,940 KB
testcase_25 AC 2,414 ms
21,144 KB
testcase_26 AC 2,441 ms
19,556 KB
testcase_27 AC 2,447 ms
21,140 KB
testcase_28 AC 2,062 ms
17,392 KB
testcase_29 AC 561 ms
9,032 KB
testcase_30 AC 593 ms
11,132 KB
testcase_31 AC 8 ms
6,940 KB
testcase_32 AC 8 ms
6,940 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <cmath>
#include <bitset>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <algorithm>
#include <complex>
#include <unordered_map>
#include <unordered_set>
#include <random>
#include <cassert>
#include <fstream>
#include <utility>
#include <functional>
#include <time.h>
#include <stack>
#include <array>
#include <list>
#include <atcoder/all>
#define popcount __builtin_popcount
using namespace std;
using namespace atcoder;
typedef long long ll;
typedef pair<int, int> P;
using mint=modint998244353;
const int MAX=1000000;
bitset<MAX> isprime;
void sieve(){
	for(int i=3; i<MAX; i++, i++) isprime[i]=1;
	isprime[2]=1;
	for(int i=3; i<MAX; i++){
		if(isprime[i]){
			for(int j=(i<<1); j<MAX; j+=i) isprime[j]=0;
		}
	}
}
ll p[MAX], n, sq;
int isq;
vector<ll> divs, pc;
inline ll idx(ll x){
	return (x<=sq)?x-1:(ll)divs.size()-n/x;
}
void calc(){
	sieve();
	while((sq+1)*(sq+1)<=n) sq++;
	for(int i=1; i<=sq; i++) divs.push_back(i);
	for(int i=sq; i>=1; i--) if(n/i>sq) divs.push_back(n/i);
	int k=0; isq=-1;
	for(int i=2; i<MAX; i++){
		if(isprime[i]){
            p[k]=i;
            if(i>sq && isq==-1) isq=k;
            k++;
		}
	}
}
void primecount(){
	vector<ll> dp=divs;
	pc.resize(divs.size(), -1);
	int l;
	for(l=0; l<divs.size() && divs[l]<p[0]*p[0]; l++){
		if(divs[l]<=1) pc[l]=0;
		else if(divs[l]==2) pc[l]=1;
		else pc[l]=2;
	}
	for(int i=1; i<=isq; i++){
		int r=lower_bound(divs.begin(), divs.end(), p[i]*p[i])-divs.begin();
		for(int j=(int)divs.size()-1; j>=l; j--){
			int k=idx(divs[j]/p[i-1]);
			if(pc[k]!=-1) dp[j]-=pc[k]-i+2;
			else dp[j]-=dp[k];
		}
		for(int j=l; j<r; j++) pc[j]=dp[j]+i-1;
		l=r;
	}
}
mint ans;
ll len;
mint c[40];
vector<mint> solve(){
	vector<mint> dp(divs.size());
	for(int i=isq-1; i>=0; i--){
		int l=lower_bound(divs.begin(), divs.end(), p[i]*p[i])-divs.begin();
		for(int j=(int)divs.size()-1; j>=l; j--){
			mint a=dp[j];
			if(p[i+1]*p[i+1]>divs[j]){
                //assert(pc[j]>=i+1);
                a=1+mint(pc[j]-i-1)*c[1];
            }
            ll x=divs[j]/p[i];
            int e=1;
            while(x){
                int k=idx(x);
                mint b=dp[k];
                if(x<p[i+1]) b=1;
                else if(p[i+1]*p[i+1]>divs[k]){
                    //assert(pc[k]>=i+1);
                    b=1+mint(pc[k]-i-1)*c[1];
                }
                a+=b*c[e];
                x/=p[i];
                e++;
            }
            dp[j]=a;
		}
	}
    for(int i=0; i<divs.size() && divs[i]<4; i++){
        dp[i]=1;
        for(int j=2; j<=divs[i]; j++){
            dp[i]+=c[1];
        }
    }
    return dp;
}
int main()
{
	cin>>len>>n;
    for(int i=1; i<40; i++){
        c[i]=mint(i+1).pow(len)-mint(i).pow(len);
    }
	calc(); primecount();
    auto dp=solve();
    // for(auto x:divs){
    //     cout<<x<<" "<<pc[idx(x)]<<" "<<dp[idx(x)].val()<<endl;
    // }
    for(auto x:divs){
        ans+=mint(x)*(dp[idx(n/x)]-dp[idx(n/(x+1))]);
    }
    cout<<ans.val()<<endl;
	return 0;
}
0