UOJ37 清華集訓2014 主旋律

2022-05-06 20:00:23 字數 1556 閱讀 8316

設 \(f(s)\) 為點集 \(s\) 中強連通生成子圖的方案數,\(cnt(s)\) 為點集 \(s\) 構成的誘導子圖中邊的個數。考慮用 \(2^\) 減去不合法方案數來計算 \(f(s)\),不合法情況即為縮點後為 \(dag\)。

設 \(h(s)\) 為點集 \(s\) 縮點後構成點數 \(>1\) 的 \(dag\) 的方案數。考慮列舉乙個點集 \(t\),其由若干個出度為 \(0\) 的強連通分量構成,那麼點集 \(s-t\) 內部的邊和連到 \(t\) 的邊可以任意選取。但這樣會算重,如果存在兩個出度為 \(0\) 的強連通分量 \(x,y\),\(t=x\) 時和 \(t=y\) 時都會算一遍,也就是合併後點集 \(s-t\) 中也可能有出度為 \(0\) 的強連通分量。因此還需進行容斥,得:

\[\large h(s)=\sum_ (-1)^2^h(s-t)

\]其中 \(size(t)\) 為點集 \(t\) 中強連通分量個數,\(e(s-t,t)\) 為點集 \(s-t\) 到點集 \(t\) 的邊數。

因為需要列舉強連通分量,所以複雜度無法接受。考慮將容斥係數放到 \(dp\) 狀態中,設 \(g(s)\) 為點集 \(s\) 構成奇數個強連通分量的方案數減去構成偶數個強連通分量的方案數。轉移就是列舉點集 \(t\),其為單獨的乙個強連通分量,為避免算重,還需確定乙個點 \(x\),讓 \(t\) 一直包含 \(x\),得:

\[\large\begin

g(s)&=f(s)-\sum_ f(t)g(s-t) \\

h(s)&=\sum_ 2^g(t)\\

f(s)&=2^-h(s)

\end

\]在轉移第 \(f(s)\) 時,要注意還不能把 \(f(s)\) 的貢獻給 \(g(s)\) 算進去。

複雜度為 \(o(3^n)\)。

#include#define maxn 35010

#define p 1000000007

#define lowbit(x) (x&(-x))

using namespace std;

typedef long long ll;

templateinline void read(t &x)

while(isdigit(c))

if(flag)x=-x;

}int n,m,all;

ll pw[maxn],siz[maxn],cnt[maxn],e[maxn],f[maxn],g[maxn],in[maxn],out[maxn];

void dfs(int s,int t)

int main()

for(int i=1;i<=m;++i) pw[i]=pw[i-1]*2%p;

for(int s=1;s<=all;++s)

siz[s]=siz[s-lowbit(s)]+1,cnt[s]=cnt[s-lowbit(s)]+siz[in[lowbit(s)]&s]+siz[out[lowbit(s)]&s];

for(int s=1;s<=all;++s)

printf("%lld",f[all]);

return 0;

}

UOJ37 清華集訓2014 主旋律

link 然後列舉縮點之後的dag的情況,考慮計算可行的邊集方案數,再遞迴乘上所有scc的匯出子圖的答案。計算可行的邊集方案數可以考慮dp,設 f s 表示點集 s 的匯出子圖中使得子圖形成乙個dag的邊集方案數,那麼可以得到轉移 f s sum limits 1 f 2 其中 cnt 表示的是起點...

UOJ 42 清華集訓2014 Sum

首先把底數 1 消掉 1 n 1 2 times n 2 1 2 times n lfloor frac n 2 rfloor times 2 令 k sqrt r 所以原式等於 begin sum limits n 1 sum limits n 1 2 times lfloor ik rfloor...

清華集訓 2014 玄學

update text update 我之前講的是個什麼鬼 如果想看看人話版本 戳這。感覺自己被坑騙了。題目明明寫了所有資料不超過int,敢情是輸入資料不超int?迷惑行為 題目感覺有點繞,我盡量 不口胡。首先我們搞一顆線段樹1,樹表示插入序列的編號。如,在q行中第i個出現插入操作 其實拿到這道題我...