QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#801568#9798. Safety Firstucup-team135TL 2991ms346256kbC++2010.5kb2024-12-07 02:32:582024-12-07 02:32:58

Judging History

你现在查看的是最新测评结果

  • [2024-12-07 02:32:58]
  • 评测
  • 测评结果:TL
  • 用时:2991ms
  • 内存:346256kb
  • [2024-12-07 02:32:58]
  • 提交

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...

result: