bzoj1494 生成樹計數 dp 矩陣快速冪

2022-04-30 01:06:13 字數 2405 閱讀 8324

題面欺詐系列...

因為乙個點最多只能連到前k個點,所以只有當前的連續k個點的連通情況是對接下來的求解有用的

那麼就可以計算k個點的所有連通情況,dfs以下發現k=5的時候有52種。

我們把它們用類似於並查集的方式表達(比如12132代表點1和點3連通,2和5連通,3自己),然後再壓縮一下。

但要注意的是,12132和23213這兩種實際對應的是一種連通情況,我們只要把它都化成字典序最小的那種就可以了

然後考慮增加乙個新點以後狀態的轉移,可以列舉這個點與前k個點(始狀態s)的連邊情況,其中有一些是不合法的:

1.連到了兩個本來就連通的點上(導致成環)

2.在1號點不與其他點連通的情況下,沒有連到1號點(導致不連通)

然後再根據連邊情況得到終狀態e,將trans[s][e]++。最後trans[i][j]表示的就是加入乙個點後由i狀態到j狀態的方案數

那麼就可以得到遞推式$f[i][j]=\sum^_$,其中f[i][j]表示以i為結尾的k個點狀態是j的方案數

那麼答案就是f[n][1](假設1是都連通的狀態)

然後初值就應該是f[k][i]=i狀態的方案數,其中i狀態的方案數為它其中每個聯通塊方案數的乘積。

那麼聯通塊的方案數怎麼算呢?其實題面已經說了...n個點的方案數就是$n^$

然後就可以愉快地dp一臉啦

容易發現遞推的形式其實和矩陣乘法是相同的,把f[i]和trans看作矩陣,就是$f[n]=f[k]*trans^$

然後就可以倍增做矩陣快速冪了。方法和整數的快速冪是一樣的。

複雜度:

k=5的狀態數接近50,$log(10^)$接近50。

所以基本上是$50^3*50=6250000$的。

**寫的很蛋疼...

1 #include2 #include3 #include4 #include5 #include6

#define ll long long

7#define inf 0x3f3f3f3f

8using

namespace

std;

9const ll maxn=1e15+5,maxs=55,p65=50000,mod=65521;10

11ll rd()

14while(c>='

0'&&c<='

9') x=x*10+c-'

0',c=getchar();

15return x*neg;16}

1718 ll n;int k,sct,num[6]=;

19ll f[maxs];

20 ll trans[2][maxs][maxs],out[2

][maxs][maxs];

21struct

st24

}sta[maxs];

25struct

mat28

};29

intmp[p65];

3031

void

print(st s)

34int

sttoint(st s)

3738

st toleast(st s)return

re;44}45

46void dfs1(int x,st s,int

m)50

for(int i=0;i<=m+1;i++)54}

5556

void dfs2(int x,st s,st from)66

for(int i=2;i<=k;i++)to.s[k]=mi;

70if(!bb) return

;71 to=toleast(to);

72//

print(from);printf("\t");print(s);printf("\t");print(to);printf("\n");

73 trans[0][mp[sttoint(from)]][mp[sttoint(to)]]++;

7475 }else78}

7980

void

sets()88}

8990

void

solve()

101}

102 }c^=1

;103

}104 memset(trans[b],0,sizeof

(trans[b]));

105for(i=1;i<=sct;i++)

110}

111 }p>>=1;b^=1

;112 }ll ans=0

;113

for(i=1;i<=sct;i++)printf("

%d\n

",ans);

116}

117118

intmain()

bzoj1494 Noi2007 生成樹計數

題意 sol 前排膜拜 雖然dalao們說了一些最小表示法啊什麼k 5時只有52種狀態啊balabala,然而我並不會.因為k很小,可以考慮用狀壓來記錄聯通塊資訊,考慮dp dp i j 表示前i個點,最後k個點聯通情況為j時的方案數 由於n很大,考慮採用矩陣快速冪優化,用並查集判環 維護 那麼最終...

uva 10766 生成樹計數

給出n,m,k,代表一家公司有n個部門,編號1到n,有m組關係,表示i和j不能直接聯通,k代表主管部門,問你有多少種分層方案。這道題的k沒有什麼用。include include include include include include include include include incl...

清華集訓2017 生成樹計數

在乙個 s 個點的圖中,存在 s n 條邊,使圖中形成了 n 個連通塊,第 i 個連通塊中有 a i 個點。現在我們需要再連線 n 1 條邊,使該圖變成一棵樹。對一種連邊方案,設原圖中第 i 個連通塊連出了 d i 條邊,那麼這棵樹 t 的價值為 mathrm t left prod m right...