題面欺詐系列...
因為乙個點最多只能連到前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...