WC2018 州區劃分

2022-05-16 10:20:46 字數 1677 閱讀 3850

題面給一張帶點權的無向圖

要求對其劃分為聯通且不存在尤拉迴路的多個子圖

定義乙個子圖的貢獻是

第\(i\)個子圖的點權和佔前\(i\)個子圖的點權和的比例的\(p\)次冪

定義乙個劃分的貢獻是

該劃分下所有子圖的貢獻的乘積

求所有劃分的貢獻之和

設\(f_s\)為選取點集為\(s\)時所有劃分的貢獻和

有\[f_s=\frac*sum_t^p}}

\]注意要求\(t\)合法

可以列舉預處理

只需保證聯通(並查集)

且沒有尤拉迴路(所有點度數為偶數)

至此複雜度\(o(3^n)\)

考慮優化

分子部分顯然是集合卷積的形式

但與普通的或卷積不同

這個式子要求兩個集合交集為空才能轉移

這裡有乙個大智若愚、苦盡甘來、有捨有得、其實就是我太菜了的做法

加一維狀態\(i\)表示所選點集的大小

這樣複雜度就乘上乙個$n^2 $啦

就可以直接或卷積轉移

具體說就是

列舉點集\(s\)和\(s-t\)大小

再直接fwtfmt轉移

這樣如果兩個集合有交集貢獻將是\(0\)

複雜度\(o(n^22^n)\)

#includeusing namespace std;

#define gc c=getchar()

#define r(x) read(x)

#define ll long long

templateinline void read(t&x)

while(isdigit(c))x*=k;

}const int n=25;

const int s=1<<21|7;

const int p=998244353;

struct edgee[n*n];

int fa[n];

int find(int x)

inline void uni(int u,int v)

inline bool in(int s,int x)

int n,m,q;

int deg[n];

inline bool check(int s)

for(int i=1;i<=m;++i)

} int lst=0;

for(int i=s;i;i^=i&(-i))

return 0;

}inline void add(int &a,int b)

inline void sub(int &a,int b)

inline ll qpow(ll a,ll b)

return ans;

}inline void fmt(int *a)

for(int i=1;i<=n;++i)fmt(g[i]);

f[0][0]=1;fmt(f[0]);

for(int i=1;i<=n;++i)

} ifmt(f[i]);

for(int k=0;k<1

} printf("%d\n",f[n][s]);

}

WC2018 州區劃分

點此看題 設d p s dp s dp s 為選出來的點狀壓為s ss,所得到的滿意度總和,轉移 d p s 1 f s i s dp i g s i dp s frac sum dp i times g s i dp s f s 1 i s d p i g s i 其中f s f s f s 是w...

WC 2018 州區劃分

給乙個無向圖 g v,e 滿足 v 21 對於某一種將 g v,e 劃分為k個的有序集合方案,若每乙個子集 g i v i,e i e i 都不存在尤拉迴路,則會對答案貢獻為 其中,x 為集合元素,w x 為元素 x 的權值。題解 被題意坑成cu 我還是太菜了 其實很顯然我們會得到乙個 dp 設 f...

WC2018 州區劃分

題目 就當那個判斷乙個州不合法的條件是存在尤拉迴路吧 一張無向圖存在尤拉迴路的條件是 圖連通不存在度數為奇數的點 於是我們列舉每乙個子集,可以在 o 2 nn 2 的時間內判斷乙個集合是否能獨立成為乙個州 之後我們設 dp i 表示選取狀態為 i 的時候的答案,s i 為這個狀態對應的城市的人口之和...