日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

AT2390-[AGC016F]Games on DAG【状压dp,SG函数】

發(fā)布時間:2023/12/3 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 AT2390-[AGC016F]Games on DAG【状压dp,SG函数】 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

正題

題目鏈接:https://www.luogu.com.cn/problem/AT2390


解題思路

nnn個點的DAGDAGDAGmmm條邊可有可無,111222上有石頭。求有多少種方案使得先手必勝。

1≤n≤15,1≤m≤n(n?1)21\leq n\leq 15,1\leq m\leq \frac{n(n-1)}{2}1n15,1m2n(n?1)?


解題思路

這個復(fù)雜度比較麻煩,要設(shè)計一個比較巧妙的dpdpdp。

考慮到題目是問多少種情況SG(1)≠SG(2)SG(1)\neq SG(2)SG(1)?=SG(2),其實求SG(1)=SG(2)SG(1)=SG(2)SG(1)=SG(2)的方案會更簡單些。

設(shè)fSf_{S}fS?表示目前只考慮了生成子圖SSSSG(1)=SG(2)SG(1)=SG(2)SG(1)=SG(2)的方案數(shù),那么若從TTT轉(zhuǎn)移到SSS時我們可以構(gòu)造一種方案使得TTT的所有點內(nèi)的SGSGSG加一,然后S/TS/TS/T的所有點的SGSGSG000。

也就相當(dāng)于我們把點按照SGSGSG大小分成若干層,然后一層一層轉(zhuǎn)移進(jìn)去。好了現(xiàn)在考慮怎么轉(zhuǎn)移fSf_SfS?,我們枚舉它的子集TTT,那么S/TS/TS/T就是它的下一層,也就是目前S/TS/TS/T內(nèi)的點SG=0SG=0SG=0。

對于TTT內(nèi)的每個點,我們需要連接至少一個S/TS/TS/T內(nèi)的點,對于S/TS/TS/T內(nèi)的點,可以隨意連接TTT內(nèi)的點,枚舉一下點集統(tǒng)計方案就好了。

時間復(fù)雜度O(3nn)O(3^nn)O(3nn)


code

#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #define ll long long using namespace std; const ll N=15,P=1e9+7; ll n,m,ans,f[1<<N],c[1<<N],e[N]; vector<int>q[N]; signed main() {scanf("%lld%lld",&n,&m);for(ll i=1;i<=m;i++){ll x,y;scanf("%lld%lld",&x,&y);x--;y--;e[x]|=(1<<y);}ll MS=(1<<n),o=0;c[0]=1;for(ll i=1;i<MS;i++)c[i]=c[i-(i&-i)]*2;for(ll s=0;s<MS;s++){if((s&1)!=((s>>1)&1))continue;f[s]=1;for(ll t=(s-1)&s;t;t=(t-1)&s){ll buf=f[t];for(ll i=0;i<n;i++){if((t>>i)&1)buf=buf*(c[(s^t)&e[i]]-1)%P;if(((s^t)>>i)&1)buf=buf*c[t&e[i]]%P;}(f[s]+=buf)%=P;}}ll ans=1;while(m)m--,ans=ans*2%P;printf("%lld\n",(ans-f[MS-1]+P)%P);return 0; }

總結(jié)

以上是生活随笔為你收集整理的AT2390-[AGC016F]Games on DAG【状压dp,SG函数】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。