QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#5451 | #622. 多项式多点求值 | Qingyu | 100 ✓ | 6326ms | 576960kb | C++17 | 9.6kb | 2020-12-27 16:30:18 | 2021-12-19 06:19:55 |
Judging History
answer
#pragma GCC optimize(3)
#include <bits/stdc++.h>
typedef long long ll;
constexpr int mod = 998244353;
const int N = 6e6 + 50;
const int g = 3;
inline int lc(int o) { return o << 1; }
inline int rc(int o) { return o << 1 | 1; }
inline int inc(int x, int y) { x += y - mod; return x + (x >> 31 & mod); }
inline int dec(int x, int y) { x -= y; return x + (x >> 31 & mod); }
inline int mul(int x, int y) { return 1ll * x * y % mod; }
struct Math
{
int fact[N], factinv[N], inv_e[N];
inline int fastpow(int x, ll p)
{
int res = 1;
while (p)
{
if (p & 1) res = mul(res, x);
x = mul(x, x);
p >>= 1;
}
return res;
}
inline int inv(int x)
{
if (x < N) return inv_e[x];
return fastpow(x, mod - 2);
}
Math()
{
fact[0] = factinv[0] = inv_e[0] = 1;
for (int i = 1; i < N; ++i) fact[i] = mul(i, fact[i - 1]);
factinv[N - 1] = fastpow(fact[N - 1], mod - 2);
for (int i = N - 2; i >= 1; --i) factinv[i] = mul(i + 1, factinv[i + 1]);
for (int i = 1; i < N; ++i) inv_e[i] = mul(fact[i - 1], factinv[i]);
}
} mt;
struct Poly
{
std::vector<int> v;
Poly() { }
Poly(std::vector<int> v) : v(v) {}
Poly(std::initializer_list<int> v) : v(v) {}
inline int deg() const { return v.size() - 1; }
inline void redeg(int k) { v.resize(k + 1); }
inline Poly slice(int k) const
{
if (k < v.size())
return std::vector<int>(v.begin(), v.begin() + k + 1);
std::vector<int> a(v);
a.resize(k + 1);
return a;
}
inline Poly clone() const { return slice(deg()); }
inline void reverse() { std::reverse(v.begin(), v.end()); }
inline void shrink()
{
int c = deg();
while (c >= 0 && v[c] == 0) --c;
v.resize(c + 1);
}
inline int& operator[](int k)
{
if (v.size() <= k) v.resize(k + 1);
return v[k];
}
inline int operator[](int k) const
{
return v.size() <= k ? 0 : v[k];
}
inline int* base() { return v.begin().base(); }
inline const int* base() const { return v.begin().base(); }
inline void print() const
{
for (auto x : v) printf("%d ", x);
putchar('\n');
}
inline Poly inv() const;
inline Poly derivative() const;
inline Poly integration() const;
inline Poly ln() const;
inline Poly exp() const;
inline Poly reverse() const;
inline std::vector<int> evaluation(const std::vector<int> &vals) const;
inline void interpolation(const std::vector<std::pair<int, int> > &points);
Poly(std::vector<std::pair<int, int> > points) { interpolation(points); }
};
struct FFT
{
int len, k;
int omega[N], omegaInv[N], rev[N];
inline void init(int n)
{
int last_len = len;
len = 1, k = 0;
while (len <= n) len <<= 1, ++k;
if (last_len == len) return;
for (int i = 0; i < len; ++i) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (k - 1));
omega[0] = omegaInv[0] = 1;
const int primitive = mt.fastpow(g, (mod - 1) / len);
for (int i = 1; i < len; ++i) omega[i] = omegaInv[len - i] = mul(omega[i - 1], primitive);
}
inline void operator() (Poly &a, const int *w)
{
if (a.v.size() < len) a.v.resize(len);
for (int i = 0; i < len; ++i) if (i < rev[i]) std::swap(a.v[i], a.v[rev[i]]);
for (int h = 1; h < len; h <<= 1)
for (int t = len / (h << 1), j = 0; j < len; j += (h << 1))
{
const int *wn = w;
for (int i = j; i < j + h; ++i)
{
const int _1 = a.v[i], _2 = mul(a.v[i + h], *wn);
a.v[i] = inc(_1, _2);
a.v[i + h] = dec(_1, _2);
wn += t;
}
}
if (w == omegaInv)
{
const int factor = mod - (mod - 1) / len;
for (int i = 0; i < len; ++i) a.v[i] = mul(a.v[i], factor);
}
}
inline void operator() (Poly &a, int op)
{
if (op == 1) operator()(a, omega);
if (op == -1) operator()(a, omegaInv);
}
} ntt;
inline Poly operator+(const Poly &P, const Poly &Q)
{
Poly R;
int deg = std::max(P.deg(), Q.deg());
for (int i = 0; i <= deg; ++i) R[i] = inc(P[i], Q[i]);
return R;
}
inline Poly operator-(const Poly &P, const Poly &Q)
{
Poly R;
int deg = std::max(P.deg(), Q.deg());
for (int i = 0; i <= deg; ++i) R[i] = dec(P[i], Q[i]);
return R;
}
inline Poly operator*(const Poly &_P, const Poly &_Q)
{
Poly P = _P.clone(), Q = _Q.clone();
int deg = P.deg() + Q.deg();
Poly R;
if (P.deg() + Q.deg() <= 200)
{
for (int i = 0; i <= P.deg(); ++i)
for (int j = 0; j <= Q.deg(); ++j)
R[i + j] = inc(R[i + j], mul(P[i], Q[j]));
return R.slice(deg);
}
else
{
ntt.init(P.deg() + Q.deg() );
ntt(P, 1); ntt(Q, 1);
for (int i = 0; i < ntt.len; ++i) R[i] = mul(P[i], Q[i]);
ntt(R, -1);
return R.slice(deg);
}
}
inline Poly PolyInv(const Poly &A)
{
Poly Ax, R;
int n = A.deg();
if (n == 0) return Poly({ mt.inv(A[0]) });
R = PolyInv(A.slice(A.deg() >> 1));
ntt.init(A.deg() << 1);
Ax = A.clone();
ntt(Ax, 1); ntt(R, 1);
for (int i = 0; i < ntt.len; ++i) Ax[i] = dec(mul(Ax[i], R[i]), 1);
for (int i = 0; i < ntt.len; ++i) R[i] = mul(R[i], dec(1, Ax[i]));
ntt(R, -1);
R.redeg(n);
return R;
}
inline Poly Poly::inv() const
{
return PolyInv(*this);
}
inline Poly Poly::derivative() const
{
Poly R;
for (int i = 0; i < deg(); ++i) R[i] = mul(i + 1, operator[](i + 1));
return R;
}
inline Poly Poly::integration() const
{
Poly R;
for (int i = 1; i <= deg(); ++i) R[i] = mul(mt.inv(i), operator[](i - 1));
return R;
}
inline Poly Poly::ln() const
{
return (derivative() * inv()).integration().slice(deg());
}
inline Poly PolyExp(const Poly &A)
{
Poly Ax, Ay, R;
int n = A.deg();
if (n == 0) return Poly({1});
R = PolyExp(A.slice(n >> 1)).slice(n);
Ax = R.ln();
Ay = A.slice(n);
ntt.init(2 * n);
ntt(R, 1), ntt(Ax, 1), ntt(Ay, 1);
for (int i = 0; i < ntt.len; ++i)
R[i] = mul(R[i], dec(inc(1, Ay[i]), Ax[i]));
ntt(R, -1);
return R;
}
inline Poly Poly::exp() const
{
return PolyExp(*this).slice(deg());
}
inline std::pair<Poly, Poly> PolyDiv(const Poly &F, const Poly &G)
{
Poly Fx, Gx, GrInv, Px, P, Q;
int n = F.deg(), m = G.deg();
Fx = F.clone(), Gx = G.clone();
Fx.reverse(); Gx.reverse(); Fx.redeg(n - m + 1);
Gx.redeg(std::max(m, n - m)); GrInv = Gx.inv();
P = Fx * GrInv;
P.redeg(n - m); P.reverse(); Gx = G.clone();
Q = Gx * P; Q.redeg(m - 1);
for (int i = 0; i <= m - 1; ++i) Q[i] = dec(F[i], Q[i]);
return std::make_pair(Q, P);
}
inline Poly operator%(const Poly &P, const Poly &Q) { return PolyDiv(P, Q).first; }
inline Poly operator/(const Poly &P, const Poly &Q) { return PolyDiv(P, Q).second; }
inline Poly Mul_T(const Poly &a, const Poly &b)
{
Poly R, A = a.clone(), B = b.clone();
if (A.deg() <= 200)
{
for (int i = a.deg(); i >= 0; --i)
for (int j = std::max(0, i - (a.deg() - b.deg())); j <= std::min(i, b.deg()); ++j)
R[i - j] = inc(R[i - j], mul(a[i], b[j]));
return R;
}
else
{
B.reverse();
ntt.init(A.deg());
ntt(A, 1); ntt(B, 1);
for (int i = 0; i < ntt.len; ++i) A[i] = mul(A[i], B[i]);
ntt(A, -1);
int c = 0;
for (int i = b.deg(); i <= a.deg(); ++i) R[c++] = A[i];
return R;
}
}
inline std::vector<int> Poly::evaluation(const std::vector<int> &vals) const
{
std::vector<Poly> T, F;
int m = vals.size();
int t = std::max(deg(), (int)vals.size() - 1);
ntt.init(t);
T.resize(t * 4); F.resize(t * 4);
std::function<void(int, int, int)> solve = [&](int o, int l, int r)
{
T[0].redeg(-1);
if (l == r) T[o] = Poly({1, dec(0, vals[l])});
else
{
const int mid = l + r >> 1;
solve(lc(o), l, mid); solve(rc(o), mid + 1, r);
T[o] = T[lc(o)] * T[rc(o)];
}
};
std::function<void(int, int, int, std::vector<int>&)> solve2 = [&](int o, int l, int r, std::vector<int> &ans)
{
if (l >= m) return;
if (l == r) ans.push_back(F[o][0]);
else
{
const int mid = l + r >> 1;
F[lc(o)] = Mul_T(F[o], T[rc(o)]);
F[rc(o)] = Mul_T(F[o], T[lc(o)]);
solve2(lc(o), l, mid, ans); solve2(rc(o), mid + 1, r, ans);
}
};
solve(1, 0, t);
Poly Q = T[1].inv();
Q.redeg(t);
Q.reverse();
Poly R = Q * *this;
for (int i = t; i <= R.deg(); ++i) F[1][i - t] = R[i];
F[1].redeg(t);
std::vector<int> ans;
solve2(1, 0, t, ans);
return ans;
}
inline void Poly::interpolation(const std::vector<std::pair<int, int> > &points)
{
int n = points.size();
std::vector<Poly> T(n << 2);
std::vector<int> vals;
for (auto v : points) vals.push_back(v.first);
std::function<void(int, int, int)> solve = [&](int o, int l, int r)
{
if (l == r) T[o] = Poly({ dec(0, vals[l]), 1 });
else
{
const int mid = l + r >> 1;
solve(lc(o), l, mid); solve(rc(o), mid + 1, r);
T[o] = T[lc(o)] * T[rc(o)];
}
};
solve(1, 0, n - 1);
Poly g = T[1], dg = g.derivative();
std::vector<int> ys = dg.evaluation(vals);
std::function<Poly(int, int, int)> solve2 = [&](int o, int l, int r)
{
if (l == r) return Poly({ mul(points[l].second, mt.inv(ys[l])) });
const int mid = l + r >> 1;
return solve2(lc(o), l, mid) * T[rc(o)] + solve2(rc(o), mid + 1, r) * T[lc(o)];
};
*this = solve2(1, 0, n - 1);
}
inline char nc()
{
static char buf[1000000], *p1 = buf, *p2 = buf;
return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1000000, stdin), p1 == p2) ? EOF : *p1++;
}
inline int read()
{
int res = 0;
char ch;
do ch = nc(); while (ch < 48 || ch > 57);
do res = res * 10 + ch - 48, ch = nc(); while (ch >= 48 && ch <= 57);
return res;
}
int main()
{
int n = read() - 1, m = read(), t = std::max(n, m - 1);
Poly P;
for (int i = 0; i <= n; ++i) P[i] = read();
std::vector<int> vals;
for (int i = 0; i < m; ++i) vals.push_back(read());
std::vector<int> result = P.evaluation(vals);
for (auto v : result) printf("%d\n", v);
return 0;
}
详细
Test #1:
score: 20
Accepted
time: 72ms
memory: 75996kb
input:
100 94 575336069 33153864 90977269 80162592 25195235 334936051 108161572 14050526 356949084 797375084 805865808 286113858 995555121 938794582 458465004 379862532 563357556 293989886 273730531 13531923 113366106 126368162 405344025 443053020 475686818 734878619 338356543 661401660 834651229 527993675 144406394 378702795 37103065 620155262 386200819 687769223 720799109 633363778 220363528 486270209 495546404 568285636 546469553 547464490 456299149 851438618 974938642 505021716 551788648 962128802 ...
output:
940122667 397187437 905033404 346709388 146347009 49596361 125616024 966474950 693596552 162411542 248699477 217639076 254290825 963991654 951375739 431661136 587466850 933820245 135676159 683994808 821695954 675479292 463904298 15085475 183389374 976945620 668527277 98940366 909505808 904450031 968010385 173752422 653990367 303219309 6056931 554452378 488226286 332464785 610244217 516229529 125358101 533797869 439485040 161852365 733105817 105926146 106606714 630873105 857340320 87011036 678661...
result:
ok 94 numbers
Test #2:
score: 20
Accepted
time: 73ms
memory: 77492kb
input:
5000 4999 410683245 925831211 726803342 144364185 955318244 291646122 334752751 893945905 484134283 203760731 533867267 813509277 491860093 413174124 584582617 594704162 976489328 978500071 196938934 628117769 169796671 858963950 562124570 582491326 647830593 238623335 20782490 674939336 656529076 238201224 657476464 10300038 590252533 468302687 287260562 719784076 907422891 533089046 672068066 229682183 373964848 244302770 117858543 11284821 961238173 246595260 517257997 870099722 351419275 538...
output:
683038054 713408290 776843174 52275065 602085453 905088100 991748340 720305324 831850056 296147844 79380797 882313010 941965313 987314872 363655479 380838721 51243733 165728533 592641557 679475455 651115426 60492203 787012426 247557193 136399242 484592897 908383514 735275879 648228244 443933835 550490997 625071079 774045911 554901737 448447574 512455509 498500488 216099918 604133346 174995590 498132830 268296096 49651043 561289208 330398949 69288559 8784168 82132295 185994726 946290818 953472996...
result:
ok 4999 numbers
Test #3:
score: 20
Accepted
time: 162ms
memory: 89968kb
input:
30000 29995 536696866 881441742 356233606 594487396 991820796 695996817 7219464 149265950 843761437 329761701 260625152 80366362 598729314 133794090 12808683 67477659 320740422 878134577 879383179 940923483 660160621 18082378 886078389 524050341 35092018 137623841 988429688 258507355 138475726 757260406 127159828 417276756 586475417 26303169 572405083 944790202 566630572 474491009 320429623 194763885 174090432 732341110 942823560 276480235 170424410 95316057 838567371 692322276 655016111 4555558...
output:
319541931 71523627 374970852 25715597 36244629 300490421 920015579 97305810 949802809 507599156 733158280 569689405 234576135 266469534 141265915 989761030 221701009 895284489 707865101 547950933 844193939 688358883 642066256 113618699 877631874 804170817 455115375 47621629 66017800 747477619 281472115 923128701 301471998 505022080 461303133 560502815 595576539 848682480 835359115 166820633 579725395 119328881 237146267 291505646 983151226 839610961 696265452 115738219 353386994 620070023 765455...
result:
ok 29995 numbers
Test #4:
score: 20
Accepted
time: 614ms
memory: 124644kb
input:
100000 99989 703908936 826436271 431732352 607460686 960390248 897906950 506352459 662618885 172508812 713410533 704313866 156459539 879660919 98030681 46358006 400134234 121190289 498201666 616888945 210891377 39623412 687350951 269444705 980768130 381802923 553892268 644461704 287608268 554761733 569616189 350624224 369805 882217037 672505285 227060683 101650396 365754412 844206684 573112907 157130192 338903039 879091569 870660644 698674844 513049853 480084099 371430418 943011467 44916984 8753...
output:
135579851 646286631 74078131 432534100 405499800 291350098 736555983 833523488 132230969 377599489 208993791 503865639 149603681 279216057 477463117 247401241 643979698 478954375 436185030 471378650 234144621 390722547 788177217 69823556 516048238 562200936 507083023 201497639 482025143 173466674 959752800 285281141 26703854 941765225 169981375 991697030 483548376 418821898 431112160 854644793 193452981 620608943 158637607 480389012 386906366 730401124 265607339 758806621 997953757 768924917 470...
result:
ok 99989 numbers
Test #5:
score: 20
Accepted
time: 6326ms
memory: 576960kb
input:
1000000 999998 326289172 459965021 432610030 381274775 890620650 133203219 755508578 820410129 100497878 978894337 34545975 484258543 341383383 556328539 705716773 985485996 201697555 806763870 456757110 445252781 501965590 655584951 516373423 475444481 554722275 106826011 433893131 385018453 687541322 148360017 545514961 595515236 437004728 787030520 480851576 368306115 160716250 515391381 14500734 159363046 564219952 598965450 866554878 545880928 547245599 863841250 661982619 980345860 8824065...
output:
606800783 817370938 237396973 847847757 644743839 247401674 83642110 430778992 481194348 734716471 284931123 740118779 149843259 354488296 948569346 267724213 148740992 487034502 874993826 268358083 945290837 793539526 571516423 380887985 556022428 430319434 939322 456132883 774969519 361006565 239058092 613185432 752196961 499650503 443579264 169840128 206218157 784814657 716427524 77823989 556319910 619497898 787301377 226345635 627609765 459532636 852381995 667636041 913081886 163159298 77598...
result:
ok 999998 numbers