牛客挑战赛58 E 大水题 (分段打表)

E 大水题

原题链接
在这里插入图片描述
G ( x ) G(x) G(x) 仍然可看作是一个多项式, G ( 1 ) G(1) G(1) 即是我们所求的答案,于是就可以打表,发现将 a i a_i ai k k k 随意更改都不影响答案,答案怎样都是 n ! n! n!

所以我们现在就要求 n !   %   m o d n!\ \% \ mod n! % mod ,我们发现当 n ≥ m o d n \geq mod nmod 时答案肯定是 0 0 0 ,毕竟这个时候 n ! n! n! 可以整除 m o d mod mod 。当 n < m o d n < mod n<mod ,我们发现还是有很多项,但是我们发现某个答案可以从任意一个更小的答案得来(毕竟是 n ! n! n! ),所以这个时候我们可以使用分段打表,即设置一个合理的步长,先暴力把每个整除步长的点打出来(如代码中注释部分)然后直接 cv 进数组。求答案就是先找到相应段,再递推,即可得到答案(代码更好理解)。

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 1e4 + 10;
const ll mod = 998244353;

ll p[N] = {1,295201906,160030060,957629942,545208507,213689172,760025067,939830261,506268060,39806322,808258749,440133909,686156489,741797144,390377694,12629586,544711799,104121967,495867250,421290700,117153405,57084755,202713771,675932866,79781699,956276337,652678397,35212756,655645460,468129309,761699708,533047427,287671032,206068022,50865043,144980423,111276893,259415897,444094191,593907889,573994984,892454686,566073550,128761001,888483202,251718753,548033568,428105027,742756734,546182474,62402409,102052166,826426395,159186619,926316039,176055335,51568171,414163604,604947226,681666415,511621808,924112080,265769800,955559118,763148293,472709375,19536133,860830935,290471030,851685235,242726978,169855231,612759169,599797734,961628039,953297493,62806842,37844313,909741023,689361523,887890124,380694152,669317759,367270918,806951470,843736533,377403437,945260111,786127243,80918046,875880304,364983542,623250998,598764068,804930040,24257676,214821357,791011898,954947696,183092975};

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif
    ll seg = 10000000;
    ll n; cin >> n;
    if (n >= mod) {
        puts("0");
        return 0;
    }
    ll ans = p[n / seg];
    for (ll i = n / seg * seg + 1; i <= n; ++i) {
        ans = ans * i % mod;
    }
    cout << ans;
    // ll f = 1;
    // printf("1,");
    // for (ll i = 1; i < mod; ++i) {
    //     f = f * i % mod;
    //     if (i % seg == 0) {
    //         printf("%lld,", f);
    //     }
    // }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值