Submission #49762974
Source Code Expand
#include <bits/stdc++.h>
#include <atcoder/modint>
const int MOD=998244353;
using mint = atcoder::static_modint<MOD>;
using namespace std;
typedef long long ll;
#define rep(i,a,n) for (ll i=a;i<(ll)(n);i++)
ll read(){ll r;scanf("%lld",&r);return r;}
const int N=17;
mint f[1<<N]; // = mask内连成一个连通块 且无剩余蓝红的方案数
mint g[1<<N]={1}; // = mask内无剩余蓝红的方案数, 红=蓝, g[] = 个数!
mint ans[1<<N]; // sum s的所有方案的连通块个数
array<int,2> rb[1<<N];
array<int,2> rbm[1<<N]; // red blue mask
int LG[1<<N];
mint fac[100010]={1};
array<int,2> operator+(const array<int,2>&a0,const array<int,2>&a1){ return {a0[0]+a1[0],a0[1]+a1[1]}; }
int main(){
rep(i,0,N) LG[1<<i]=i;
rep(i,1,100000+1) fac[i]=fac[i-1]*i;
int n=read();
int m=read();
rep(i,0,m) rb[1<<(read()-1)][0]++;
rep(i,0,m) rb[1<<(read()-1)][1]++;
rep(msk,1,1<<n) rbm[msk] = rbm[msk&(msk-1)] + rb[msk&-msk]; // 统计msk 红蓝
rep(msk,1,1<<n) g[msk] = rbm[msk][0]==rbm[msk][1]?fac[rbm[msk][0]]:0; // 红==蓝,则 红!
rep(msk,1,1<<n) {
f[msk] = g[msk];
// submsk != msk, submsk \subset msk, submsk 包含msk最低位, submsk + revsubmsk = msk
int lowbit = msk&-msk;
int highbits = msk-lowbit;
if(highbits) for(int revsubmsk=highbits;revsubmsk != 0;revsubmsk=(revsubmsk-1)&highbits){
f[msk] -= f[lowbit + (highbits-revsubmsk)]*g[revsubmsk];
}
}
rep(msk,1,1<<n){
int lowbit = msk&-msk;
int highbits = msk-lowbit;
for(int revsubmsk=highbits;;revsubmsk=(revsubmsk-1)&highbits){
ans[msk] += f[lowbit + (highbits-revsubmsk)]*(ans[revsubmsk] + g[revsubmsk]);
if(revsubmsk==0)break;
}
}
printf("%d\n",(ans[(1<<n)-1]*fac[m].inv()).val());
return 0;
}
// n个part
// m 红终端, i -> ri part
// m 蓝终端, i -> bi part
// m cables 连接 红<->蓝
// 同一个part可以连多个终端
// 每个终端只能一条cable, 所以一共m!方案连接cable
// s = 连接方案中连通块 块的个数
// 求 exp(s)
//
// 简化
// n个part点, n 17
// m 1e5
// m个左侧点
// m个右侧点
// 给定 每个单侧点 连接了一个part点
// 每个左侧点连接了一个右侧点,每个右侧点连接了一个左侧点
// f[mask] = mask内连成一个连通块 且无剩余蓝红的方案数
// g[mask] = mask内无剩余蓝红的方案数
// ans[s] = sum s的所有方案的连通块个数
// ans[s] = for mask, mask 包含最小点
// f[mask] * ans[s-mask] 两边互不影响计算右边
// + 1 * g[mask] 计算左边
//
// g[mask] = sum红! , 满足sum红==sum蓝
// f[mask] = g[mask] - sum f[submask]*g[mask-submask], submask包含mask中最小的
Submission Info
| Submission Time |
|
| Task |
G - Electric Circuit |
| User |
cromarmot |
| Language |
C++ 20 (gcc 12.2) |
| Score |
600 |
| Code Size |
2657 Byte |
| Status |
AC |
| Exec Time |
388 ms |
| Memory |
6924 KiB |
Compile Error
Main.cpp: In function ‘ll read()’:
Main.cpp:8:21: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
8 | ll read(){ll r;scanf("%lld",&r);return r;}
| ~~~~~^~~~~~~~~~~
Judge Result
| Set Name |
Sample |
All |
| Score / Max Score |
0 / 0 |
600 / 600 |
| Status |
|
|
| Set Name |
Test Cases |
| Sample |
00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt |
| All |
00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt, 01_m_small_00.txt, 01_m_small_01.txt, 01_m_small_02.txt, 01_m_small_03.txt, 01_m_small_04.txt, 02_m_large_00.txt, 02_m_large_01.txt, 02_m_large_02.txt, 02_m_large_03.txt, 02_m_large_04.txt, 02_m_large_05.txt, 02_m_large_06.txt, 02_m_large_07.txt, 02_m_large_08.txt, 02_m_large_09.txt, 02_m_large_10.txt, 02_m_large_11.txt, 02_m_large_12.txt, 02_m_large_13.txt, 02_m_large_14.txt, 02_m_large_15.txt, 02_m_large_16.txt, 02_m_large_17.txt, 02_m_large_18.txt, 02_m_large_19.txt, 02_m_large_20.txt, 02_m_large_21.txt, 03_bipartite_00.txt, 03_bipartite_01.txt, 03_bipartite_02.txt, 03_bipartite_03.txt, 03_bipartite_04.txt |
| Case Name |
Status |
Exec Time |
Memory |
| 00_sample_00.txt |
AC |
2 ms |
5864 KiB |
| 00_sample_01.txt |
AC |
375 ms |
6756 KiB |
| 00_sample_02.txt |
AC |
2 ms |
5656 KiB |
| 01_m_small_00.txt |
AC |
124 ms |
6192 KiB |
| 01_m_small_01.txt |
AC |
125 ms |
6212 KiB |
| 01_m_small_02.txt |
AC |
124 ms |
6276 KiB |
| 01_m_small_03.txt |
AC |
2 ms |
5672 KiB |
| 01_m_small_04.txt |
AC |
374 ms |
6764 KiB |
| 02_m_large_00.txt |
AC |
385 ms |
6860 KiB |
| 02_m_large_01.txt |
AC |
385 ms |
6856 KiB |
| 02_m_large_02.txt |
AC |
387 ms |
6860 KiB |
| 02_m_large_03.txt |
AC |
388 ms |
6708 KiB |
| 02_m_large_04.txt |
AC |
385 ms |
6908 KiB |
| 02_m_large_05.txt |
AC |
385 ms |
6796 KiB |
| 02_m_large_06.txt |
AC |
386 ms |
6792 KiB |
| 02_m_large_07.txt |
AC |
384 ms |
6740 KiB |
| 02_m_large_08.txt |
AC |
386 ms |
6704 KiB |
| 02_m_large_09.txt |
AC |
385 ms |
6700 KiB |
| 02_m_large_10.txt |
AC |
386 ms |
6624 KiB |
| 02_m_large_11.txt |
AC |
386 ms |
6596 KiB |
| 02_m_large_12.txt |
AC |
385 ms |
6800 KiB |
| 02_m_large_13.txt |
AC |
384 ms |
6852 KiB |
| 02_m_large_14.txt |
AC |
386 ms |
6800 KiB |
| 02_m_large_15.txt |
AC |
385 ms |
6708 KiB |
| 02_m_large_16.txt |
AC |
385 ms |
6860 KiB |
| 02_m_large_17.txt |
AC |
384 ms |
6908 KiB |
| 02_m_large_18.txt |
AC |
384 ms |
6856 KiB |
| 02_m_large_19.txt |
AC |
385 ms |
6916 KiB |
| 02_m_large_20.txt |
AC |
386 ms |
6856 KiB |
| 02_m_large_21.txt |
AC |
385 ms |
6796 KiB |
| 03_bipartite_00.txt |
AC |
384 ms |
6924 KiB |
| 03_bipartite_01.txt |
AC |
383 ms |
6764 KiB |
| 03_bipartite_02.txt |
AC |
384 ms |
6800 KiB |
| 03_bipartite_03.txt |
AC |
384 ms |
6908 KiB |
| 03_bipartite_04.txt |
AC |
384 ms |
6708 KiB |