QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#801568 | #9798. Safety First | ucup-team135 | TL | 2991ms | 346256kb | C++20 | 10.5kb | 2024-12-07 02:32:58 | 2024-12-07 02:32:58 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
mt19937 rnd;
#define app push_back
#define all(x) (x).begin(),(x).end()
#ifdef LOCAL
#define debug(...) [](auto...a){ ((cout << a << ' '), ...) << endl;}(#__VA_ARGS__, ":", __VA_ARGS__)
#define debugv(v) do {cout<< #v <<" : {"; for(int izxc=0;izxc<v.size();++izxc) {cout << v[izxc];if(izxc+1!=v.size()) cout << ","; }cout <<"}"<< endl;} while(0)
#else
#define debug(...)
#define debugv(v)
#endif
#define lob(a,x) lower_bound(all(a),x)
#define upb(a,x) upper_bound(all(a),x)
const int MOD = 998244353;
const long long MOD2 = (long long) MOD * MOD;
const int root = 3;
const int alim = 64; // Bound for using O(n^2) polynomial mult
int modpow(int b, int e) {
int ans = 1;
for (; e; b = (long long) b * b % MOD, e /= 2)
if (e & 1) ans = (long long) ans * b % MOD;
return ans;
}
const int MODinv = 2 - MOD; // pow(-MOD, -1, 2**32)
inline int m_reduce(long long x) {
int m = x * MODinv;
return (x>>32) - (((long long) m * MOD) >> 32);
}
const int r2 = modpow(2, 64);
inline int m_transform(int x) {
return m_reduce((long long)x * r2);
}
inline int m_add(int x, int y) {
int z = x + y;
return z < 0 ? z + MOD : z - MOD;
}
inline int m_sub(int x, int y) {
int z = x - y;
return z < 0 ? z + MOD : z - MOD;
}
inline int m_mult(int x, int y) {
return m_reduce((long long) x * y);
}
vector<int> rt = {1};
vector<int> transformed_rt;
vector<int> transformed_rt2;
template<int a>
void transform(vector<int> &P) {
int m = P.size();
int n = m / a;
int size = rt.size();
while (2 * size < n) {
rt.resize(n / 2);
int r = modpow(root, MOD / (4 * size));
for (int i = 0; i < size; ++i)
rt[i + size] = (long long) r * rt[i] % MOD;
size *= 2;
}
// For montgomery
for (int i = transformed_rt.size(); i < rt.size(); ++i) {
transformed_rt.resize(rt.size());
transformed_rt[i] = m_transform(rt[i]);
transformed_rt2.resize(rt.size());
transformed_rt2[i] = (unsigned int) MODinv * transformed_rt[i];
}
int k = n;
while (k >= 4) k /= 4;
if (k == 2) {
int step = n * a;
int half_step = step / 2;
for (int j1 = 0; j1 < half_step; ++j1) {
int j2 = j1 + half_step;
int diff = m_sub(P[j1], P[j2]);
P[j1] = m_add(P[j1], P[j2]);
P[j2] = diff;
}
k = n/2;
} else {
k = n;
}
for (; k > 1; k /= 4) {
for (int i = 0; i < n/k; ++i) {
int step = k * a;
int half_step = step / 2;
int quarter_step = half_step / 2;
int R20 = transformed_rt2[2 * i];
int RR0 = transformed_rt[2 * i];
int R21 = transformed_rt2[2 * i + 1];
int RR1 = transformed_rt[2 * i + 1];
int R2 = transformed_rt2[i];
int RR = transformed_rt[i];
int j1 = i * step;
int j2 = j1 + quarter_step;
int j3 = j2 + quarter_step;
int j4 = j3 + quarter_step;
for (int j = 0; j < quarter_step; ++j, ++j1, ++j2, ++j3, ++j4) {
int z0;
{
int z = P[j3];
int m = (unsigned int) R2 * z;
z0 = ((long long) z * RR - (long long) m * MOD) >> 32;
}
int z1;
{
int z = P[j4];
int m = (unsigned int) R2 * z;
z1 = ((long long) z * RR - (long long) m * MOD) >> 32;
}
int sum0 = m_add(P[j1], z0);
int diff0 = m_sub(P[j1], z0);
int sum1 = P[j2] + z1;
int diff1 = P[j2] - z1;
// [sum0, sum1, diff0, diff1]
int zz0;
{
int z = sum1;
int m = (unsigned int) R20 * z;
zz0 = ((long long) z * RR0 - (long long) m * MOD) >> 32;
}
int zz1;
{
int z = diff1;
int m = (unsigned int) R21 * z;
zz1 = ((long long) z * RR1 - (long long) m * MOD) >> 32;
}
P[j1] = m_add(sum0, zz0);
P[j2] = m_sub(sum0, zz0);
P[j3] = m_add(diff0, zz1);
P[j4] = m_sub(diff0, zz1);
}
}
}
for (int i = 0; i < m; ++i)
if (P[i] < 0) P[i] += MOD;
}
template<int a>
void inverse_transform(vector<int> &P) {
int m = P.size();
int n = m / a;
int n_inv = m_transform(modpow(n, MOD - 2));
vector<int> rev(n);
for (int i = 1; i < n; ++i) {
rev[i] = rev[i / 2] / 2 + (i & 1) * n / 2;
}
// P = [p * n_inv for p in P]
for (int i = 0; i < m; ++i)
P[i] = m_mult(n_inv, P[i]);
// P = [P[a * rev[i // a] + (i % a)] for i in range(m)]
for (int i = 1; i < n; ++i)
if (i < rev[i])
swap_ranges(P.begin() + a * i, P.begin() + a * i + a, P.begin() + a * rev[i]);
// P = [P[-a * (i // a) + (i % a)] for i in range(m)]
for (int i = 1; i < n/2; ++i)
swap_ranges(P.begin() + a * i, P.begin() + a * i + a, P.begin() + a * (n - i));
transform<a>(P);
// P = [P[a * rev[i // a] + (i % a)] for i in range(m)]
for (int i = 1; i < n; ++i)
if (i < rev[i])
swap_ranges(P.begin() + a * i, P.begin() + a * i + a, P.begin() + a * rev[i]);
}
template<int a>
void fast_polymult_mod(vector<int> &P, vector<int> &Q) {
int m = P.size();
int n = m / a;
transform<a>(P);
transform<a>(Q);
vector<int> &PQ = P;
for (int i = 0; i < n; ++i) {
vector<unsigned long long> res(2 * a);
for (int j = 0; j < a; ++j) {
if (j >= 10 && j % 9 == 8)
for (int k = j; k < j + a - 10; ++k)
res[k] -= (res[k] >> 63) * 9 * MOD2;
for (int k = 0; k < a; ++k)
res[j + k] += (long long) P[i * a + j] * Q[i * a + k];
}
int c = rt[i/2];
if (i & 1) c = MOD - c;
for (int j = 0; j < a; ++j)
PQ[i * a + j] = (res[j] + c * (res[j + a] % MOD)) % MOD;
}
inverse_transform<a>(PQ);
}
template <size_t... N>
void work(std::index_sequence<N...>, int x, std::vector<int>& a, std::vector<int>& b) {
static void (*ptrs[])(std::vector<int>&, std::vector<int>&) = {&fast_polymult_mod<N+1>...};
ptrs[x - 1](a, b);
}
void fast_polymult(vector<int> &P, vector<int> &Q) {
int m1 = P.size();
int m2 = Q.size();
int res_len = m1 + m2 - 1;
int b = 1;
while ((alim << b) < res_len) ++b;
int a = ((res_len - 1) >> b) + 1;
int m = a << b;
P.resize(m);
Q.resize(m);
// Call fast_polymult_mod<a>(P, Q);
work(std::make_index_sequence<alim>{}, a, P, Q);
P.resize(res_len);
}
vector<int> operator *(vector<int> v1,vector<int> v2)
{
fast_polymult(v1,v2);
return v1;
}
const int p=998244353;
int po(int a,int b) {if(b==0) return 1; if(b==1) return a; if(b%2==0) {int u=po(a,b/2);return (u*1LL*u)%p;} else {int u=po(a,b-1);return (a*1LL*u)%p;}}
int inv(int x) {return po(x,p-2);}
const int B=2005;
const int maxn=2*B;
int f[B][B];
int fact[maxn];int invf[maxn];
vector<int> rev(vector<int> A)
{
int n=A.size();
vector<int> v1(n),v2(n+1);
for(int i=0;i<n;++i) {v1[i]=(A[i]*1LL*fact[i])%p;}
for(int diff=0;diff<n;++diff) {v2[n-diff]=(diff%2==0 ? invf[diff] : (p-invf[diff])%p);}
vector<int> v3=v1*v2;
vector<int> B(n);
for(int i=0;i<n;++i)
{
B[i]=(v3[n+i]*1LL*invf[i])%p;
}
return B;
}
vector<int> rev2(vector<int> A)
{
int n=A.size();
vector<int> v1(n),v2(n+1);
for(int i=0;i<n;++i) {v1[i]=(A[i]*1LL*fact[i])%p;}
for(int diff=0;diff<n;++diff) {v2[n-diff]=(invf[diff]);}
vector<int> v3=v1*v2;
vector<int> B(n);
for(int i=0;i<n;++i)
{
B[i]=(v3[n+i]*1LL*invf[i])%p;
}
return B;
}
int h[maxn][maxn];int Q[maxn][maxn];
int res[maxn][maxn];
int C[maxn][maxn];
int32_t main()
{
ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
for(int i=0;i<maxn;++i)
{
for(int j=0;j<=i;++j)
{
if(j==0 || j==i) {C[i][j]=1;continue;}
C[i][j]=C[i-1][j]+C[i-1][j-1];if(C[i][j]>=p) C[i][j]-=p;
}
}
fact[0]=1; for(int i=1;i<maxn;++i) {fact[i]=(fact[i-1]*1LL*i)%p;} for(int i=0;i<maxn;++i) {invf[i]=inv(fact[i]);}
f[0][0]=1;
for(int d=B-1;d>=1;--d)
{
for(int nx=B-1;nx>=0;--nx)
{
for(int nz=(B-1)/d;nz>=0;--nz)
{
if(nx+d+1<B && nz+1<B)
{
f[nx+d+1][nz+1]-=f[nx][nz];if(f[nx+d+1][nz+1]<0) f[nx+d+1][nz+1]+=p;
}
}
}
vector<int> AA,BB;
for(int nx=0;nx<B-d;++nx)
{
AA.clear();BB.clear();
int deg=(B-1)/d;
for(int i=0;i<deg;++i)
{
AA.app(f[nx][i]);
}
while(!AA.empty() && AA.back()==0) {AA.pop_back();}
if(AA.empty()) continue;
BB=rev(AA);
for(int i=0;i<BB.size();++i)
{
if(i+d<B && nx+d<B)
{
h[nx+d][i+d]+=BB[i];if(h[nx+d][i+d]>=p) h[nx+d][i+d]-=p;
}
if(i+d-1<B && nx+d<B)
{
h[nx+d][i+d-1]-=BB[i];if(h[nx+d][i+d-1]<0) h[nx+d][i+d-1]+=p;
}
}
}
}
vector<int> AA,BB;
for(int nx=0;nx<B;++nx)
{
AA.clear();BB.clear();
int deg=B;
for(int i=0;i<deg;++i)
{
AA.app(h[nx][i]);
}
while(!AA.empty() && AA.back()==0) {AA.pop_back();}
if(AA.empty()) continue;
BB=rev2(AA);
for(int i=0;i<BB.size();++i)
{
h[nx][i]=BB[i];
}
}
Q[0][0]=1;
for(int d=B-1;d>=1;--d)
{
for(int nx=0;nx<B-d;++nx)
{
for(int nz=(B-1)/d;nz>=0;--nz)
{
if(nx+d<B && nz+1<B)
{
Q[nx+d][nz+1]+=Q[nx][nz];if(Q[nx+d][nz+1]>=p) Q[nx+d][nz+1]-=p;
}
}
}
}
vector<int> h1(2*B*B),Q1(2*B*B);
for(int i=0;i<B;++i)
{
for(int j=0;j<B;++j)
{
h1[2*B*i+j]=h[i][j];
Q1[2*B*i+j]=Q[i][j];
}
}
//vector<int> h2(B*B),h3(B*B),Q2(B*B),Q3(B*B);
//for(int i=0;i<B*B;++i) {h2[i]=h1[i];h3[i]=h1[i+B*B];Q2[i]=Q1[i];Q3[i]=Q1[i+B*B];}
vector<int> res1=h1*Q1;
for(int i=0;i<B;++i)
{
for(int j=0;j<B;++j)
{
int el=2*i*B+j;
res[i][j]=res1[el];
}
}
int t;cin>>t;
while(t--)
{
int n,m;cin>>n>>m;
int answ=0;
for(int d=1;d<=n;++d)
{
answ+=(res[m][d]*1LL*C[n-1][d-1])%p;if(answ>=p) answ-=p;
}
cout<<answ<<'\n';
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 2714ms
memory: 345388kb
input:
3 1 3 2 3 3 3
output:
1 4 10
result:
ok 3 number(s): "1 4 10"
Test #2:
score: 0
Accepted
time: 2707ms
memory: 345920kb
input:
1 2000 2000
output:
204576309
result:
ok 1 number(s): "204576309"
Test #3:
score: 0
Accepted
time: 2716ms
memory: 345288kb
input:
100000 10 1752 19 171 17 1105 14 687 28 204 3 1215 19 1610 30 764 6 537 42 656 41 943 36 795 28 795 9 740 28 1138 20 173 6 1160 21 1409 18 851 28 301 30 782 4 685 10 1792 15 868 42 1341 10 1361 4 1278 28 61 30 1943 44 1199 23 1398 25 1199 34 951 14 866 4 1469 4 1060 30 567 22 1805 50 1566 39 537 25 ...
output:
268773463 258398110 748990072 944261206 28848324 1415323 440426423 133920075 975812871 422247730 443385987 269602349 516611815 864790546 323341799 910043327 459119274 782783928 662557529 928314001 831289605 119493832 694722015 789549109 307680352 415179306 774755603 202375583 226239893 400583167 282...
result:
ok 100000 numbers
Test #4:
score: 0
Accepted
time: 2749ms
memory: 345628kb
input:
100000 98 437 75 1936 82 522 51 1166 67 1452 96 618 96 1436 91 1173 100 1242 69 1280 74 125 73 869 77 811 73 1694 56 1550 65 1857 75 941 79 538 68 1057 71 907 90 1925 86 785 65 1658 60 1044 67 804 56 1428 53 127 97 197 57 680 81 1636 64 1200 79 790 92 1389 91 340 78 411 58 1308 70 952 90 85 91 1397 ...
output:
742593766 791182960 260925178 423870975 954765117 233028625 298697835 166927245 254797666 165773109 608132753 508968899 726675390 951161570 757337043 102586936 115466851 787049646 41560035 882840713 26484816 898027489 538836045 445749214 446547003 117114483 182473853 404451392 352694143 378208316 32...
result:
ok 100000 numbers
Test #5:
score: 0
Accepted
time: 2782ms
memory: 346012kb
input:
100000 129 1388 106 1862 143 434 143 681 126 1765 109 1644 144 123 142 1142 138 973 124 1795 121 973 131 392 147 1656 132 207 112 1853 126 1122 120 1251 103 1925 142 1140 115 1297 129 132 125 1533 126 1227 142 7 102 1513 133 858 149 1762 134 1855 141 1217 123 977 122 1460 129 1541 108 183 104 533 12...
output:
440317711 139768075 565993626 901858704 349245942 647922261 533399827 724222147 877395158 917502675 325080714 245930347 299162783 345803447 367132017 623799987 636190810 118577120 325019366 243129164 269236125 558129393 787577029 336286916 717132852 881434705 601429865 126037636 341589865 889242064 ...
result:
ok 100000 numbers
Test #6:
score: 0
Accepted
time: 2775ms
memory: 344756kb
input:
100000 161 204 198 236 164 128 170 67 178 1767 166 1558 161 1092 177 35 196 484 186 1852 186 1771 197 1642 196 547 163 454 190 538 170 427 198 243 153 24 154 376 158 1944 192 1612 168 1857 167 576 179 879 167 1792 151 1796 155 1548 185 413 169 1174 154 147 168 823 175 1886 184 1468 184 1436 182 1848...
output:
172213650 39226856 245140705 351049088 622302277 619509932 83846312 413497682 488845784 643322899 291252918 392636859 317943186 240120915 942222009 859975525 946587026 684244937 63714812 701449725 307104716 656890895 639328477 649490103 388256744 77822051 439206921 229542510 781413486 353732575 2507...
result:
ok 100000 numbers
Test #7:
score: 0
Accepted
time: 2799ms
memory: 346180kb
input:
100000 249 1689 202 290 201 1758 205 1974 224 859 225 1404 237 1225 233 1537 229 1855 208 1514 225 427 236 1163 221 1767 205 1090 210 1747 212 1595 238 1397 222 474 208 797 238 865 202 454 241 762 242 825 202 476 225 1651 249 1402 238 55 232 1492 246 1425 209 44 247 1195 233 839 220 132 229 1720 219...
output:
478896065 389378364 985754036 339457290 317564442 238034798 309343251 975492930 113847787 837055938 639686562 389971277 427781065 524689817 271482752 29043143 758402389 480502530 280382698 778767560 786854567 692046693 274827770 691633514 548570489 980915638 703593445 290234486 159460105 825773786 5...
result:
ok 100000 numbers
Test #8:
score: 0
Accepted
time: 2865ms
memory: 346256kb
input:
100000 284 484 280 887 281 706 288 982 265 139 252 1771 274 1693 265 1178 291 1816 274 1399 262 1735 256 382 298 1727 263 1573 275 1158 269 1148 295 1855 271 1846 299 1930 265 1066 282 5 263 689 263 319 300 184 290 1799 269 346 286 1413 258 107 276 968 290 695 264 1089 300 565 289 12 278 9 270 1341 ...
output:
788345977 153327425 175203272 175973972 433579709 28443509 542941637 125034554 288677440 651395165 539742635 446883576 893484563 386570008 821704436 986842055 405743220 214946204 772942087 172320952 317542644 994457259 905260561 720455208 19612908 936949071 878179138 725633300 680798312 429632808 56...
result:
ok 100000 numbers
Test #9:
score: 0
Accepted
time: 2888ms
memory: 345680kb
input:
100000 335 1149 328 420 314 908 333 457 311 436 343 1633 347 482 342 636 344 773 328 106 326 1956 324 142 332 1592 308 422 313 1269 339 1175 308 1239 341 1086 324 228 330 278 309 591 324 674 319 1371 329 771 340 1794 328 62 330 595 301 1963 350 1489 303 1316 350 229 302 498 310 1119 301 1314 309 158...
output:
466829660 555532898 409746105 578569521 769440372 2964768 307023301 191386338 94476448 18774209 725183049 726204726 156444031 615404413 971836582 153240471 350605612 950904415 519251422 190842679 334593063 535831679 579194005 162554264 940105611 595871343 892799212 631565608 490043538 188581175 9801...
result:
ok 100000 numbers
Test #10:
score: 0
Accepted
time: 2919ms
memory: 345912kb
input:
100000 376 1267 354 1825 386 1074 382 1921 394 370 360 1456 357 665 380 1018 395 1137 363 1208 364 721 365 1070 390 448 370 1980 390 1392 371 1083 366 492 357 763 357 1432 361 822 397 1116 394 1002 358 1840 389 1723 360 1330 387 307 373 1123 369 159 383 176 382 1602 365 51 381 663 377 289 371 996 35...
output:
390253031 316787247 26462866 796298428 226183959 763080011 285937268 348142933 663866612 415181296 717569775 588413734 431000914 620523197 629378051 519455457 158359587 849533799 841515711 15339270 65428008 987517355 724009665 338388777 835526477 302484643 683704214 367172103 190625812 896253381 293...
result:
ok 100000 numbers
Test #11:
score: 0
Accepted
time: 2968ms
memory: 345420kb
input:
100000 434 588 432 815 450 1418 412 1884 433 126 439 77 412 388 423 631 410 1014 442 1022 434 993 440 42 420 1227 446 560 416 831 439 982 440 962 441 654 446 1892 440 1320 406 221 405 699 429 466 434 267 412 842 438 1240 433 22 441 1013 446 403 402 1197 421 365 436 209 404 1964 431 1905 425 1185 437...
output:
207541749 336833274 881422547 827346611 70971321 454257920 154139314 510981588 13377934 490870112 444424948 139517186 593785414 304008128 991806197 789860487 200104450 171438083 200400903 729206302 3269775 136654208 154480081 965938881 33796074 153387776 855734088 872836628 335883197 509629206 68803...
result:
ok 100000 numbers
Test #12:
score: 0
Accepted
time: 2991ms
memory: 346036kb
input:
100000 498 1140 453 628 461 1049 451 1076 486 307 498 1969 467 1281 487 742 480 168 472 1373 464 165 482 446 474 1321 453 740 454 503 464 1350 484 1921 492 1533 485 1466 458 655 463 1842 455 1654 463 1946 469 1670 466 877 492 574 452 914 472 1438 470 39 483 1514 456 160 483 678 465 253 500 1083 456 ...
output:
565577857 194207901 707193298 613954291 230290622 304782069 404818548 543201352 746901819 617211749 71591506 922305993 198339187 194403017 493251415 109494570 425648759 399865843 119104127 611830721 102201541 506278480 882381710 307917236 224024569 137492356 145220138 582902017 71781896 82649438 759...
result:
ok 100000 numbers
Test #13:
score: -100
Time Limit Exceeded
input:
100000 549 972 542 743 504 327 540 1176 507 1823 536 1613 542 1566 507 775 548 484 515 601 519 1984 549 951 544 1948 504 478 510 1621 524 1856 538 1540 542 1361 530 1243 528 779 507 839 525 404 511 888 537 14 538 725 509 1839 526 1604 545 89 547 1749 537 1847 520 1976 526 1730 507 114 538 1140 522 1...
output:
853927693 490442688 983465 576083671 659822629 619863844 636908261 485043933 3083678 248131385 958597481 2762630 756548542 514131507 679677683 781924009 40277939 936178970 881756007 391802886 410564977 340227570 530588833 451614191 731358456 645856448 993622086 431164470 465717764 351316769 14448812...