除草 Hackerrank思考題

2021-06-26 16:50:47 字數 2553 閱讀 8568

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.一間囚房裡關押著兩個犯人。每天監獄都會為這間囚房提供一罐湯,讓這兩個犯人自己來分。起初,這兩個人經常會發生爭執,因為他們總是有人認為對方的湯比自己的多。後來他們找到了乙個兩全其美的辦法 乙個人分湯,讓另乙個人先選。於是爭端就這麼解決了。可是,現在這間囚房裡又加進來乙個新犯人,現在是三個人來分湯。...