QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#256101 | #7754. Rolling For Days | ucup-team135# | TL | 292ms | 185544kb | C++20 | 9.1kb | 2023-11-18 17:51:49 | 2023-11-18 17:51:50 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
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);}
template<int M, int K, int G> struct Fft {
// 1, 1/4, 1/8, 3/8, 1/16, 5/16, 3/16, 7/16, ...
int g[1 << (K - 1)];
Fft() : g() { //if tl constexpr...
static_assert(K >= 2, "Fft: K >= 2 must hold");
g[0] = 1;
g[1 << (K - 2)] = G;
for (int l = 1 << (K - 2); l >= 2; l >>= 1) {
g[l >> 1] = (static_cast<long long>(g[l]) * g[l]) % M;
}
assert((static_cast<long long>(g[1]) * g[1]) % M == M - 1);
for (int l = 2; l <= 1 << (K - 2); l <<= 1) {
for (int i = 1; i < l; ++i) {
g[l + i] = (static_cast<long long>(g[l]) * g[i]) % M;
}
}
}
void fft(vector<int> &x) const {
const int n = x.size();
assert(!(n & (n - 1)) && n <= 1 << K);
for (int h = __builtin_ctz(n); h--; ) {
const int l = 1 << h;
for (int i = 0; i < n >> 1 >> h; ++i) {
for (int j = i << 1 << h; j < ((i << 1) + 1) << h; ++j) {
const int t = (static_cast<long long>(g[i]) * x[j | l]) % M;
if ((x[j | l] = x[j] - t) < 0) x[j | l] += M;
if ((x[j] += t) >= M) x[j] -= M;
}
}
}
for (int i = 0, j = 0; i < n; ++i) {
if (i < j) std::swap(x[i], x[j]);
for (int l = n; (l >>= 1) && !((j ^= l) & l); ) {}
}
}
vector<int> convolution(const vector<int> &a, const vector<int> &b) const {
if(a.empty() || b.empty()) return {};
const int na = a.size(), nb = b.size();
int n, invN = 1;
for (n = 1; n < na + nb - 1; n <<= 1) invN = ((invN & 1) ? (invN + M) : invN) >> 1;
vector<int> x(n, 0), y(n, 0);
std::copy(a.begin(), a.end(), x.begin());
std::copy(b.begin(), b.end(), y.begin());
fft(x);
fft(y);
for (int i = 0; i < n; ++i) x[i] = (((static_cast<long long>(x[i]) * y[i]) % M) * invN) % M;
std::reverse(x.begin() + 1, x.end());
fft(x);
x.resize(na + nb - 1);
return x;
}
};
Fft<998244353,23,31> muls;
vector<int> form(vector<int> v,int n)
{
while(v.size()<n) v.push_back(0);
while(v.size()>n) v.pop_back();
return v;
}
vector<int> operator *(vector<int> v1,vector<int> v2)
{
return muls.convolution(v1,v2);
}
vector<int> operator +(vector<int> v1,vector<int> v2)
{
while(v2.size()<v1.size()) v2.push_back(0); while(v1.size()<v2.size()) v1.push_back(0);
for(int i=0;i<v1.size();++i) {v1[i]+=v2[i];if(v1[i]>=p) v1[i]-=p; else if(v1[i]<0) v1[i]+=p;}
return v1;
}
vector<int> operator -(vector<int> v1,vector<int> v2)
{
int sz=max(v1.size(),v2.size());while(v1.size()<sz) v1.push_back(0); while(v2.size()<sz) v2.push_back(0);
for(int i=0;i<sz;++i) {v1[i]-=v2[i];if(v1[i]<0) v1[i]+=p; else if(v1[i]>=p) v1[i]-=p;} return v1;
}
vector<int> trmi(vector<int> v)
{
for(int i=1;i<v.size();i+=2) {if(v[i]>0) v[i]=p-v[i]; else v[i]=(-v[i]);}
return v;
}
vector<int> deriv(vector<int> v)
{
if(v.empty()) return{};
vector<int> ans(v.size()-1);
for(int i=1;i<v.size();++i) ans[i-1]=(v[i]*1LL*i)%p;
return ans;
}
vector<int> integ(vector<int> v)
{
vector<int> ans(v.size()+1);ans[0]=0;
for(int i=1;i<v.size();++i) ans[i-1]=(v[i]*1LL*i)%p;
return ans;
}
vector<int> mul(vector<vector<int> > v)
{
if(v.size()==1) return v[0];
vector<vector<int> > v1,v2;for(int i=0;i<v.size()/2;++i) v1.push_back(v[i]); for(int i=v.size()/2;i<v.size();++i) v2.push_back(v[i]);
return muls.convolution(mul(v1),mul(v2));
}
vector<int> inv1(vector<int> v,int n)
{
assert(v[0]!=0);
int sz=1;v=form(v,n);vector<int> a={inv(v[0])};
while(sz<n)
{
vector<int> vsz;for(int i=0;i<min(n,2*sz);++i) vsz.push_back(v[i]);
vector<int> b=((vector<int>) {1})-muls.convolution(a,vsz);
for(int i=0;i<sz;++i) assert(b[i]==0);
b.erase(b.begin(),b.begin()+sz);
vector<int> c=muls.convolution(b,a);
for(int i=0;i<sz;++i) a.push_back(c[i]);
sz*=2;
}
return form(a,n);
}
vector<int> inv(vector<int> v,int n)
{
v=form(v,n);assert(v[0]!=0);if(v.size()==1) {return {inv(v[0])};} vector<int> v1=trmi(v);
vector<int> a=v1*v;a=form(a,2*n);
vector<int> b((n+1)/2);for(int i=0;i<b.size();++i) b[i]=a[2*i];
vector<int> ans1=inv(b,b.size());vector<int> ans2(n);for(int i=0;i<n;++i) {if(i%2==0) ans2[i]=ans1[i/2]; else ans2[i]=0;}
return form(v1*ans2,n);
}
vector<int> operator/(vector<int> a,vector<int> b)
{
while(!a.empty() && a.back()==0) a.pop_back(); while(!b.empty() && b.back()==0) b.pop_back();
int n=a.size();int m=b.size();if(n<m) return {};
reverse(a.begin(),a.end());reverse(b.begin(),b.end());vector<int> ans=a*inv(b,n-m+1);while(ans.size()>n-m+1) ans.pop_back();
reverse(ans.begin(),ans.end());while(!ans.empty() && ans.back()==0) ans.pop_back();return ans;
}
vector<int> operator%(vector<int> a,vector <int> b)
{
vector<int> ans=a-b*(a/b);while(!ans.empty() && ans.back()==0) ans.pop_back(); return ans;
}
const int md = p;
const int N=12;
int sa[1<<N],sb[1<<N];
int Bit(int mask, int i) {
return (mask >> i)&1;
}
vector <int> o[12],u[1<<12];
int pr[1<<12][12][1005];
int C[1005][1005],invC[1005][1005];
int dp[1<<12][1005];
int zx[1<<12][1005];
int32_t main() {
#ifdef LOCAL
freopen("../A.in", "r", stdin);
#endif
ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
for (int i = 0; i < 1005; ++i) {C[i][0]=1;}
for (int i = 1; i < 1005; ++i) {
for (int j = 1; j < 1005; ++j) {
C[i][j] = (C[i - 1][j] + C[i - 1][j - 1])%md;
}
}
for(int i=0;i<1005;++i) for(int j=0;j<=i;++j) invC[i][j] = po(C[i][j],md-2);
int invm[1005];
for(int i=0;i<1005;++i) invm[i]=po(i,md-2);
int n, m;
cin >> m>>n;
vector <int> a(n), b(n);
for (int i = 0;i<n;++i){cin>>a[i];}
for (int i = 0;i<n;++i){cin>>b[i];}
for (int mask = 1;mask<(1<<n);++mask){
for ( int i = 0;i<n;++i){
if(Bit(mask,i)){
sa[mask]=sa[mask^(1<<i)]+a[i];
sb[mask]=sb[mask^(1<<i)]+b[i];
}
}
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < b[i]; ++j) {
o[i].push_back(C[a[i]][j]);
}
}
u[0]={1};
for (int mask = 1; mask < (1 << n); ++mask) {
for (int i = 0; i < n; ++i) {
if (Bit(mask, i)) {
u[mask] = u[mask^(1<<i)]*o[i];
break;
}
}
}
auto cf = [&] (vector <int> &a, int i) {
if (i < (int)a.size()) {
return a[i];
}
else {
return 0ll;
}
};
for (int mask = 0; mask < (1 << n); ++mask) {
bool ok = 1;
for (int i = 0; i < n; ++i) {
if (Bit(mask, i)) ok &= !!b[i];
}
if (ok) {
for (int i = 0; i < n; ++i) {
if (Bit(mask, i)) {
for (int m = b[i]; m <= sb[mask]; ++m) {
int x = cf(u[mask-(1<<i)],m-b[i]);
x *= C[a[i]][b[i]-1];
x %= md;
x *= invC[sa[mask]][m-1];x%=md;
x*=(a[i]-b[i]+1);x%=md;
x*=invm[sa[mask]-m+1];x%=md;
pr[mask][i][m]=x;
}
}
}
}
else {
}
}
for(int mask=0;mask<(1<<n);++mask)
{
for(int i=1002;i>=0;--i)
{
zx[mask][i]=zx[mask][i+1];
for(int j=0;j<n;++j)
{
if(mask & (1<<j))
{
zx[mask][i]+=pr[mask][j][i];zx[mask][i]%=md;
}
}
}
}
for (int mask = 1; mask < (1 << n); ++mask) {
bool ok = 1;
for (int i = 0; i < n; ++i) {
if (Bit(mask, i)) ok &= !!b[i];
}
if(!ok){continue;}
for (int m=sb[mask];m>=0;--m){
int sp = 0;
for (int i = 0; i < n; ++i) {
if (!Bit(mask,i)) continue;
int p2=pr[mask][i][m+1]*po(zx[mask][m+1],md-2);p2%=md;
sp += p2;sp%=md;
dp[mask][m]+=dp[mask-(1<<i)][m+1-b[i]]*p2;
dp[mask][m]%=md;
}
sp %= md;
dp[mask][m]+=dp[mask][m+1]*(md+1-sp);dp[mask][m]%=md;dp[mask][m]%=md;
dp[mask][m]+=(sa[mask]-m+sa[(1<<n)-mask-1]-sb[(1<<n)-mask-1])*invm[sa[mask]-m];
dp[mask][m]%=md;
}
}
int ma = 0;
for (int i = 0; i < n; ++i) {
if (b[i]) {
ma += 1 << i;
}
}
cout << ((dp[ma][0]%p)+p)%p;
return 0;
}
詳細信息
Test #1:
score: 100
Accepted
time: 128ms
memory: 56244kb
input:
2 2 1 1 1 1
output:
2
result:
ok answer is '2'
Test #2:
score: 0
Accepted
time: 127ms
memory: 56068kb
input:
4 2 2 2 2 1
output:
582309210
result:
ok answer is '582309210'
Test #3:
score: 0
Accepted
time: 132ms
memory: 57348kb
input:
5 5 1 1 1 1 1 0 0 0 0 1
output:
5
result:
ok answer is '5'
Test #4:
score: 0
Accepted
time: 120ms
memory: 56764kb
input:
4 4 1 1 1 1 1 1 1 0
output:
831870299
result:
ok answer is '831870299'
Test #5:
score: 0
Accepted
time: 126ms
memory: 53084kb
input:
5 2 4 1 2 1
output:
598946616
result:
ok answer is '598946616'
Test #6:
score: 0
Accepted
time: 128ms
memory: 56832kb
input:
5 2 3 2 3 1
output:
482484776
result:
ok answer is '482484776'
Test #7:
score: 0
Accepted
time: 128ms
memory: 59132kb
input:
5 5 1 1 1 1 1 0 1 1 1 0
output:
665496242
result:
ok answer is '665496242'
Test #8:
score: 0
Accepted
time: 124ms
memory: 55640kb
input:
3 3 1 1 1 1 1 0
output:
499122180
result:
ok answer is '499122180'
Test #9:
score: 0
Accepted
time: 129ms
memory: 58520kb
input:
5 5 1 1 1 1 1 1 0 1 1 1
output:
582309212
result:
ok answer is '582309212'
Test #10:
score: 0
Accepted
time: 126ms
memory: 53120kb
input:
3 2 2 1 2 0
output:
499122180
result:
ok answer is '499122180'
Test #11:
score: 0
Accepted
time: 124ms
memory: 58172kb
input:
20 5 1 6 7 2 4 0 1 3 1 4
output:
75028873
result:
ok answer is '75028873'
Test #12:
score: 0
Accepted
time: 124ms
memory: 58476kb
input:
15 5 4 2 3 4 2 2 1 1 2 1
output:
585494868
result:
ok answer is '585494868'
Test #13:
score: 0
Accepted
time: 127ms
memory: 59044kb
input:
20 4 5 4 3 8 1 2 2 3
output:
156108321
result:
ok answer is '156108321'
Test #14:
score: 0
Accepted
time: 127ms
memory: 55136kb
input:
15 2 6 9 2 8
output:
672033760
result:
ok answer is '672033760'
Test #15:
score: 0
Accepted
time: 256ms
memory: 140920kb
input:
20 12 1 2 1 1 2 4 1 3 2 1 1 1 1 0 0 1 0 0 1 0 2 0 1 1
output:
691640771
result:
ok answer is '691640771'
Test #16:
score: 0
Accepted
time: 266ms
memory: 153708kb
input:
19 12 1 1 1 2 1 2 2 1 2 4 1 1 1 1 0 1 1 0 1 1 0 2 1 0
output:
777326448
result:
ok answer is '777326448'
Test #17:
score: 0
Accepted
time: 125ms
memory: 56496kb
input:
20 2 19 1 1 1
output:
299473325
result:
ok answer is '299473325'
Test #18:
score: 0
Accepted
time: 127ms
memory: 55600kb
input:
19 2 14 5 10 1
output:
497380388
result:
ok answer is '497380388'
Test #19:
score: 0
Accepted
time: 125ms
memory: 57576kb
input:
100 5 10 25 6 19 40 0 2 4 5 11
output:
773338801
result:
ok answer is '773338801'
Test #20:
score: 0
Accepted
time: 125ms
memory: 56620kb
input:
64 5 1 12 13 33 5 1 0 1 20 0
output:
571823997
result:
ok answer is '571823997'
Test #21:
score: 0
Accepted
time: 123ms
memory: 56284kb
input:
100 4 15 38 24 23 0 20 0 1
output:
635309463
result:
ok answer is '635309463'
Test #22:
score: 0
Accepted
time: 128ms
memory: 57792kb
input:
88 5 15 25 9 19 20 8 15 9 18 17
output:
400310961
result:
ok answer is '400310961'
Test #23:
score: 0
Accepted
time: 247ms
memory: 150464kb
input:
100 12 2 2 13 9 13 7 2 1 6 15 17 13 0 0 5 7 10 7 0 1 0 0 4 4
output:
552732942
result:
ok answer is '552732942'
Test #24:
score: 0
Accepted
time: 292ms
memory: 185544kb
input:
59 12 7 6 3 5 4 6 5 2 5 6 5 5 4 5 2 5 3 6 0 2 1 0 3 3
output:
27023521
result:
ok answer is '27023521'
Test #25:
score: 0
Accepted
time: 127ms
memory: 56852kb
input:
100 3 10 60 30 0 28 21
output:
261595276
result:
ok answer is '261595276'
Test #26:
score: 0
Accepted
time: 131ms
memory: 53240kb
input:
84 2 39 45 4 23
output:
897695217
result:
ok answer is '897695217'
Test #27:
score: 0
Accepted
time: 141ms
memory: 58920kb
input:
1000 5 370 136 129 182 183 312 47 112 22 119
output:
705415872
result:
ok answer is '705415872'
Test #28:
score: 0
Accepted
time: 131ms
memory: 55524kb
input:
766 5 372 194 98 90 12 165 123 53 27 0
output:
870555094
result:
ok answer is '870555094'
Test #29:
score: 0
Accepted
time: 125ms
memory: 55068kb
input:
1000 2 374 626 175 591
output:
501708945
result:
ok answer is '501708945'
Test #30:
score: 0
Accepted
time: 124ms
memory: 56464kb
input:
701 1 701 413
output:
413
result:
ok answer is '413'
Test #31:
score: -100
Time Limit Exceeded
input:
1000 12 101 43 34 281 23 24 12 25 66 222 145 24 37 43 27 257 5 11 12 19 62 41 87 13