matrix tree
矩陣aij,表示i和j的lca的點權值,詢問矩陣的行列式
考慮首先將列按dfs序,依次開始高斯消元,假設是1-2-3,第一行第一列必定全都是w[1],因此可以直接消元,消完之後考慮2,此時所有跟2的lca為1的點必定不再2的子樹中,假設是i號點,則a2i=ai2=w[1]-w[1]=0,因此這些行是不需要用2這一行去減的,而跟2的lca不為1的點,lca必定等於2,即a2j=aj2=w[2]-w[1],因此也可以直接減,此時考慮3,若3是2的兄弟,其實情況和2相同,若是2的子節點,那麼所有lca(3,i)=1就有a3i=ai3=0,因為被1消過,卻不受2的影響,而lca(3,i)=2的情況,在2消之前,a3i=ai3=w[2]-w[1],而a2i=ai2=w[2]-w[1],故2消過之後,a3i=ai3=0,情況又跟2的情況類似,如此可以歸納一下,每次都只用把子樹所在的行減一次。
最後的結果可以觀察主對角線就是w[1]*pi(w[i]-w[fa[i]])
#include #include #include #include #include #define next nex
const int mo=1000000007;
using namespace std;
long long ans;
int n,top;
long long w[500000];
int tail[500000],ss,v[500000],st[500000];
int next[2000000],sora[2000000];
void origin()
void link(int x,int y)
void bfs(int s)
long double &real()
long double &imag()
void print()
inline complex operator-(const complex &a, const complex &b)
inline complex operator*(const complex &a, const complex &b)
inline void sincos(long double theta,long double &a,long double &b)
void fft(complex p, int n, int oper)
} complex unit_p0;
for (int d = 0; (1 << d) < n; d++)
} }}void calc(int l,int r,int e,int ans)
int mid=(l+r)>>1;
calc(l,mid,e+1,st[e][0]);
calc(mid+1,r,e+1,st[e][1]);
int la=st[e][0][0],lb=st[e][1][0],n;
for (n=1;n<=la+lb+1;n<<=1) ;
for (int i=0;i1 && !ans[ans[0]];ans[0]--) ;
// cout<
swap permutation
詢問乙個排列,相鄰交換嚴格k次,任意交換最多k次得到的排列個數是多少
考慮將第i個數放入前i-1個數的方案
用f[i][j]表示前i個數相鄰交換嚴格j次的答案是多少,由於i在i-1個數中能插的位置是i個,然後又最多只能用j次交換往前,因此f[i][j]=f[i-1][j]+f[i-1][j-1]+...+f[i-1][j-i+1]
然後考慮到i和i+1換兩次就換回來不變了,因此最後統答案的時候,將與k同奇偶的j的f[n][j]累和即可
第二問用g[i][j]表示前i個數用了嚴格j次交換的方案是多少
同樣考慮把i插進去,首先是不動就是g[i-1][j],然後是一次可以與前i-1個數任意交換,因此就是g[i-1][j-1]*(i-1)
則g[i][j]=g[i-1][j]+g[i-1][j-1]*(i-1)
最後統答案的時候就把比k小的j的g[n][j]累和即可
#include #include #include #include #include const int mo=1000000007;
using namespace std;
int n,k;
int f[5000][5000],s[5000][5000];
long long g[5000][5000];
int main()
int ans=0;
for (int j=0;j<=k;j++)
if ((j&1)==(k&1)) ans=(ans+f[n][j])%mo;
printf("%d ",ans);
g[0][0]=1;
for (int i=1;i<=n;i++)
for (int j=0;j<=k;j++)
ans=0;
for (int j=0;j<=k;j++)
ans=(ans+g[n][j])%mo;
printf("%d\n",ans);
return 0;
}
討論 思考題
1 功能 編寫函式 float fun 利用以簡單迭代方法 xn 1 cos xn 求方程 cos x x 0 的乙個實根。迭代步驟如下 1 取x1 初值為0.0 2 x0 x1 把x1 的值賦給x0 3 x1 cos x0 求出乙個新的x1 4 若x0 x1 的絕對值小於 0.000001 執行步...
討論 思考題
1 功能 請編寫函式 void fun char s n char b 將 m行n列的二維陣列中的字元資料按列的順序依次放到乙個字串中。例如 二維陣列中的資料為 w w w w s s s s h h h h 則字串中的內容應是 wshwshwshwsh 2 功能 編寫函式 void fun cha...
趣味思考題
1.一間囚房裡關押著兩個犯人。每天監獄都會為這間囚房提供一罐湯,讓這兩個犯人自己來分。起初,這兩個人經常會發生爭執,因為他們總是有人認為對方的湯比自己的多。後來他們找到了乙個兩全其美的辦法 乙個人分湯,讓另乙個人先選。於是爭端就這麼解決了。可是,現在這間囚房裡又加進來乙個新犯人,現在是三個人來分湯。...