QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#547982 | #8305. Accelerator | haze# | AC ✓ | 1726ms | 164088kb | C++23 | 11.8kb | 2024-09-05 14:22:31 | 2024-09-05 14:22:32 |
Judging History
answer
#include <cstdio>
#include <bits/stdc++.h>
#define int long long
const int maxn = 3e6 + 5, mod = 998244353;
template<typename T>
inline T max(const T &a, const T &b) {
return a > b ? a : b;
}
template<typename T>
inline void swap(T &a, T &b) {
T temp = a;
a = b;
b = temp;
}
struct IO {
IO() {};
char c;
inline char gc() {
static char buf[maxn], *p1 = buf, *p2 = buf;
return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, maxn, stdin), p1 == p2) ? EOF : *p1++;
}
template<typename T>
inline IO &operator>>(T &_) {
_ = 0;
bool f = 1;
c = gc();
while (c < '0' || c > '9') {
if (c == '-') f = 0;
c = gc();
}
while (c >= '0' && c <= '9') {
_ = _ * 10 + c - 48;
c = gc();
}
if (!f) _ = -_;
return *this;
}
char buf[maxn];
int p = 0;
~IO() { fwrite(buf, 1, p, stdout); }
inline void pc(const char &c) {
buf[p++] = c;
if (p == maxn) fwrite(buf, 1, maxn, stdout), p = 0;
}
template<typename T>
inline IO &operator<<(T x) {
if (!x) {
pc(48);
return *this;
}
static int wt[41], len;
len = 0;
if (x < 0) {
pc('-');
x = -x;
}
for (; x; x /= 10) { wt[++len] = x % 10; }
while (len) { pc(wt[len--] + 48); }
return *this;
}
inline IO &operator<<(const char &c) {
pc(c);
return *this;
}
} io;
int fastpow(int x, int y) {
if (y == 0) return 1;
int tmp = fastpow(x, y >> 1);
return y & 1 ? 1ll * tmp * tmp % mod * x % mod : 1ll * tmp * tmp % mod;
}
inline int add(int x, int y) { return x + y >= mod ? x + y - mod : x + y; }
inline int sub(int x, int y) { return x - y < 0 ? x - y + mod : x - y; }
inline void copy(int *Alpha, int *Beta, int len) {
//Alpha -> Beta
for (int i = 0; i < len; i++) Alpha[i] = Beta[i];
}
namespace Poly {
const int gate = 3, invg = fastpow(gate, mod - 2);
int lim, lg, sing[maxn];
int Gate[maxn], Invg[maxn];
int inv[maxn];
void init(int len) {
lim = 1, lg = 0;
while (lim < len) lim <<= 1, lg++;
for (int i = 1; i < lim; i++) sing[i] = (sing[i >> 1] >> 1) | ((i & 1) << (lg - 1));
}
int Hacking_to_the() {
for (int i = 1; i < maxn; i <<= 1)
Gate[i] = fastpow(gate, (mod - 1) / (i << 1)), Invg[i] = fastpow(invg, (mod - 1) / (i << 1));
// inv[1] = 1 ;for(int i=2;i<maxn;i++) inv[i] = (mod-1ll*(mod/i)*inv[mod%i]%mod) ;
return 0;
}
int GATE = Hacking_to_the();
void NTT(int *Steins, int type) {
for (int i = 0; i < lim; i++) if (i < sing[i]) swap(Steins[i], Steins[sing[i]]);
for (int len = 1; len < lim; len <<= 1) {
int unit = type == 1 ? Gate[len] : Invg[len];
for (int i = 0; i < lim; i += (len << 1)) {
int w = 1;
for (int k = 0; k < len; k++, w = 1ll * w * unit % mod) {
int x = Steins[i + k], y = 1ll * w * Steins[i + k + len] % mod;
Steins[i + k] = add(x, y), Steins[i + k + len] = sub(x, y);
}
}
}
if (type != 1) {
int Okabe = fastpow(lim, mod - 2);
for (int i = 0; i < lim; i++) Steins[i] = 1ll * Steins[i] * Okabe % mod;
}
}
void convolution(int *Alpha, int la, int *Beta, int lb, int *Zeta) {
init(la + lb - 1);
for (int i = la; i < lim; i++) Alpha[i] = 0;
for (int i = lb; i < lim; i++) Beta[i] = 0;
NTT(Alpha, 1), NTT(Beta, 1);
for (int i = 0; i < lim; i++) Zeta[i] = 1ll * Alpha[i] * Beta[i] % mod;
return NTT(Zeta, -1);
}
int g[maxn];
void get_inv(int *Alpha, int len, int *Beta) {
//使用前清空Beta数组
if (len == 1) {
Beta[0] = fastpow(Alpha[0], mod - 2);
return;
}
get_inv(Alpha, (len + 1) >> 1, Beta);
init(len + len - 1);
copy(g, Alpha, len);
for (int i = len; i < lim; i++) g[i] = 0;
NTT(Beta, 1), NTT(g, 1);
for (int i = 0; i < lim; i++) Beta[i] = 1ll * Beta[i] * (mod + 2 - 1ll * Beta[i] * g[i] % mod) % mod;
NTT(Beta, -1);
for (int i = len; i < lim; i++) Beta[i] = 0;
}
const int inv2 = fastpow(2, mod - 2);
int t[maxn];
void get_sqrt(int *Alpha, int len, int *Beta) {
//使用前清空Beta数组
if (len == 1) {
Beta[0] = 1;
return;
}
get_sqrt(Alpha, (len + 1) >> 1, Beta);
get_inv(Beta, len, t);
init(len + len - 1);
copy(g, Alpha, len);
for (int i = len; i < lim; i++) g[i] = 0;
convolution(g, len, t, len, g);
for (int i = 0; i < lim; i++) Beta[i] = 1ll * inv2 * (Beta[i] + g[i]) % mod;
for (int i = len; i < lim; i++) Beta[i] = 0;
for (int i = 0; i < lim; i++) t[i] = 0;
}
void derivative(int *Alpha, int len, int *Beta) {
for (int i = 1; i < len; i++) Beta[i - 1] = 1ll * i * Alpha[i] % mod;
Beta[len - 1] = 0;
}
void integral(int *Alpha, int len, int *Beta) {
for (int i = len - 1; i >= 1; i--) Beta[i] = 1ll * Alpha[i - 1] * inv[i];
Beta[0] = 0;
}
int f1[maxn], f2[maxn];
void get_ln(int *Alpha, int len, int *Beta) {
memset(f2, 0, sizeof(f2));
derivative(Alpha, len, f1), get_inv(Alpha, len, f2);
convolution(f1, len, f2, len, Beta);
return integral(Beta, len, Beta);
}
int e1[maxn], e2[maxn];
void get_exp(int *Alpha, int len, int *Beta) {
//使用前清空Beta数组
if (len == 1) return void(Beta[0] = 1);
get_exp(Alpha, (len + 1) >> 1, Beta);
get_ln(Beta, len, e1);
init(len + len - 1);
for (int i = 0; i < len; i++) e2[i] = sub(Alpha[i], e1[i]);
for (int i = len; i < lim; i++) e2[i] = 0;
NTT(e2, 1), NTT(Beta, 1);
for (int i = 0; i < lim; i++) Beta[i] = 1ll * Beta[i] * (e2[i] + 1) % mod;
NTT(Beta, -1);
for (int i = len; i < lim; i++) Beta[i] = 0;
for (int i = 0; i < lim; i++) e1[i] = 0;
}
int g1[maxn], g2[maxn], g3[maxn];
void division(int *Alpha, int la, int *Beta, int lb, int *Zeta, int *Gamma) {
//Zeta's length requires 2la-lb
if (la < lb) {
for (int i = 0; i <= la - lb; i++) Zeta[i] = 0;
for (int i = la; i < lb; i++) Gamma[i] = 0;
return copy(Gamma, Alpha, la);
}
for (int i = 0; i < la; i++) g1[i] = Alpha[la - i - 1];
for (int i = 0; i < lb; i++) g2[i] = Beta[lb - i - 1];
for (int i = lb; i <= la - lb; i++) g2[i] = 0;
lim = 1;
while (lim <= (la - lb) << 1) lim <<= 1;
for (int i = 0; i < lim; i++) g3[i] = 0;
get_inv(g2, la - lb + 1, g3);
convolution(g1, la, g3, la - lb + 1, Zeta);
for (int i = 0; i < la - lb - i; i++) swap(Zeta[i], Zeta[la - lb - i]);
for (int i = la - lb + 1; i < lim; i++) Zeta[i] = 0;
copy(g1, Beta, lb);
copy(g2, Zeta, la - lb + 1);
convolution(g1, lb, g2, la - lb + 1, g1);
for (int i = 0; i < lb; i++) Gamma[i] = sub(Alpha[i], g1[i]);
}
}
namespace Multi_point {
int *gate[maxn << 2];
void init(int now, int l, int r, int *Alpha) {
if (l == r) {
gate[now] = new int[2];
gate[now][0] = mod - Alpha[l], gate[now][1] = 1;
return;
}
int mid = (l + r) >> 1, lim = 1;
while (lim < r - l + 1 + 1) lim <<= 1;
gate[now] = new int[lim];
int *g1 = new int[lim], *g2 = new int[lim];
init(now << 1, l, mid, Alpha), init(now << 1 | 1, mid + 1, r, Alpha);
copy(g1, gate[now << 1], mid - l + 1 + 1);
copy(g2, gate[now << 1 | 1], r - mid + 1);
return Poly::convolution(g1, mid - l + 1 + 1, g2, r - mid + 1, gate[now]);
}
void evaluation(int now, int l, int r, int *Alpha, int *Beta, int *Zeta) {
//Alpha->f(x),Beta->S{x}
if (r - l + 1 <= 256) {
for (int i = l; i <= r; i++) {
int answer = 0;
int base = 1;
for (int j = 0; j <= r - l; j++, base = 1ll * base * Beta[i] % mod)
answer = (answer + 1ll * base * Alpha[j]) % mod;
Zeta[i] = answer;
}
return;//Which makes it faster;
}
int mid = (l + r) >> 1, lim = 1;
while (lim < r - l + 1 + 1) lim <<= 1;
int *g1, *g2;
g1 = new int[lim << 1], g2 = new int[lim];
Poly::division(Alpha, r - l + 1, gate[now << 1], mid - l + 1 + 1, g1, g2);
evaluation(now << 1, l, mid, g2, Beta, Zeta);
Poly::division(Alpha, r - l + 1, gate[now << 1 | 1], r - mid + 1, g1, g2);
evaluation(now << 1 | 1, mid + 1, r, g2, Beta, Zeta);
delete[] g1, delete[] g2;
}
int g1[maxn], g2[maxn];
void Evaluation(int *Alpha, int len, int *Beta, int n, int *Zeta) {
init(1, 1, n, Beta);
Poly::division(Alpha, len, gate[1], n + 1, g1, g2);
return evaluation(1, 1, n, g2, Beta, Zeta);
}
int f1[maxn], f2[maxn], ell[maxn];
int *Steins[maxn << 1], e1[maxn], e2[maxn], G1[maxn], G2[maxn];
void interpolation(int now, int l, int r) {
if (l == r) {
Steins[now] = new int[1];
return void(Steins[now][0] = ell[l]);
}
Steins[now] = new int[r - l + 1];
int mid = (l + r) >> 1, lim = 1;
interpolation(now << 1, l, mid), interpolation(now << 1 | 1, mid + 1, r);
while (lim < (r - l + 1)) lim <<= 1;
copy(G1, Steins[now << 1], mid - l + 1), copy(G2, Steins[now << 1 | 1], r - mid);
copy(e1, gate[now << 1 | 1], r - mid + 1), copy(e2, gate[now << 1], mid - l + 1 + 1);
Poly::convolution(e1, r - mid + 1, G1, mid - l + 1, e1);
Poly::convolution(e2, mid - l + 1 + 1, G2, r - mid, e2);
for (int i = 0; i <= r - l; i++) Steins[now][i] = (e1[i] + e2[i]) % mod;
}
void Interpolation(int *Alpha, int *Beta, int n, int *Zeta) {
//Alpha->x,Beta->y
init(1, 1, n, Alpha);
copy(f1, gate[1], n + 1);
Poly::derivative(f1, n + 1, f2);
evaluation(1, 1, n, f2, Alpha, ell);
for (int i = 1; i <= n; i++) ell[i] = 1ll * Beta[i] * fastpow(ell[i], mod - 2) % mod;
interpolation(1, 1, n);
return copy(Zeta, Steins[1], n);
}
}
typedef long long ll;
int n;
ll Alpha[maxn], Beta[maxn], Zeta[maxn];
ll fr[maxn];
ll C(ll N1, ll M1){
return fr[M1] * fr[N1 - M1] % mod * fastpow(fr[N1], mod - 2) % mod;
}
void solve() {
scanf("%lld", &n);
ll K = 1;
for (int i = 1; i <= n; i++)
scanf("%lld", &Alpha[i]), Beta[i] = 0, K *= Alpha[i], K %= mod;
Alpha[++ n] = 0, Beta[n] = K;
Multi_point::Interpolation(Alpha, Beta, n, Zeta);
ll ans = 0, inv = fastpow(Zeta[n - 1], mod - 2);
for (int i = 0; i < n - 1; i++){
if(((i ^ n) & 1))ans += C(n - 1, i) * Zeta[i] % mod;
else ans -= C(n - 1, i) * Zeta[i] % mod;
ans %= mod;
}
ans = (ans * inv) % mod;
io << (ans + mod) % mod << '\n';
}
signed main() {
int T;
fr[0] = 1;
for(int i =1 ; i < 100000 + 10; ++ i){
fr[i] = fr[i - 1] * i % mod;
}
scanf("%lld", &T);
while (T--) {
solve();
}
// scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d%d",&Alpha[i],&Beta[i]);
// Multi_point::Interpolation(Alpha,Beta,n,Zeta);
// for(int i=0;i<n;i++) io << Zeta[i] << " \n"[i==n-1];
// return 0;
}
这程序好像有点Bug,我给组数据试试?
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 3ms
memory: 53772kb
input:
3 3 1 2 3 1 10 4 5 5 5 5
output:
665496247 10 780
result:
ok 3 lines
Test #2:
score: 0
Accepted
time: 0ms
memory: 55580kb
input:
100 1 847297038 5 203751343 825662680 957256277 500052871 818834331 5 987146111 742744954 629579339 780044373 494679147 8 251614896 194569580 916578218 533049529 530535094 733501237 367273760 385341463 7 375252389 260364079 389447501 409464874 846572964 772775526 503458256 2 123436633 211941084 6 19...
output:
847297038 51970068 170556219 113431915 760262074 246542542 195147099 493093785 168144980 126946554 710105918 669760399 717542211 546162274 355117267 476319791 504479282 611041492 409057254 586259120 411524107 467323677 604713606 677086599 337208713 428207507 929439958 108098278 655034669 220455699 6...
result:
ok 100 lines
Test #3:
score: 0
Accepted
time: 13ms
memory: 55540kb
input:
100 34 426400575 9927300 909720899 954255675 767998905 83905549 11564853 733479914 519688252 588206942 292994501 808946771 354495122 756030286 580925234 595222682 950714227 281486657 916585766 73918645 344801620 269358971 823314063 624176199 663573632 222827631 43334235 771899654 651401397 286161985...
output:
407047195 969184260 707290913 588793971 161624956 900764379 946042111 525481567 323619066 559679400 702641543 774077417 72041789 230297993 843180691 511827230 391868728 132163026 337301045 628148033 958328653 291354147 301471681 130398071 507222983 737846714 753300919 174373074 657380065 424492703 8...
result:
ok 100 lines
Test #4:
score: 0
Accepted
time: 239ms
memory: 88896kb
input:
100 718 404314538 399059943 992580922 926005407 338582419 649174215 974473772 173983508 842966562 421761508 29390122 51320322 611981261 892915925 76490050 235705837 849990374 33308970 67066467 977102595 675867852 125129873 255787127 312018985 952054434 722094045 171206475 890973351 126578304 3894293...
output:
995895670 994710069 713279557 626113157 685298699 907804742 382977068 204900737 784029914 680667123 403672352 99600221 456001194 444900792 239883144 340277780 204991006 861302818 509148571 413682190 7764599 301884750 936011407 341104983 78171640 403819556 641759875 377501122 207128991 70300471 37527...
result:
ok 100 lines
Test #5:
score: 0
Accepted
time: 107ms
memory: 69104kb
input:
1 8852 816257371 319861135 553044271 273391499 11309408 53548475 289068275 1599437 411634506 987136158 664105085 160956635 487913416 362514958 559857483 193029215 643883605 898606968 522890545 923619097 395182091 392324487 336898192 775191603 206906215 853876583 959896034 34058934 708850658 39009214...
output:
922706515
result:
ok single line: '922706515'
Test #6:
score: 0
Accepted
time: 1726ms
memory: 164088kb
input:
1 100000 566231680 552288735 269188130 832541422 403127222 314561085 693183364 216515795 91683984 754348153 872058608 487774703 990409975 718741890 508226988 309131993 285659464 917930011 933970844 911199697 737428687 529296820 389084211 395195075 750526573 985616979 885567650 915693886 901620354 56...
output:
440511824
result:
ok single line: '440511824'
Extra Test:
score: 0
Extra Test Passed