1028考試總結

2022-05-07 17:30:11 字數 3929 閱讀 2672

​ 題目大意:

​ 給定乙個排列,為這個排列字典序的下乙個排列是啥?\(n <= 1e5\).(不能用next_permutation.)

​ 從後往前找第乙個\(x_i < x_\)的數,這個數\(i\)之後的數是單調遞減的.也就是說這個數後面的已經是極大的了,不能通過改變順序是後面這幾個數更大,所以我們只能增大\(i\)位置上的這個數,在後面的數中找乙個比它大的最小的數,讓他倆交換位置,剩下沒選過的數就從小到大排一遍序就好了.

#include using namespace std;

inline long long read()

const int n = 1e5 + 5;

int n, p[n], vis[n];

int main()

} if(pos == 0) for(int i = 1;i <= n; i++) printf("%d ", i);

else

if(!tag)

for(int i = 1;i <= pos; i++) printf("%d ", p[i]);

for(int i = 1;i <= n; i++) if(vis[i]) printf("%d ", i); }

fclose(stdin); fclose(stdout);

return 0;

}

​ 題目大意:給定一棵樹,再給出所有的葉子結點經過的順序,然後從根節點1開始走,每條邊最多走兩次,最後回到根節點,問是否可以走出一條路徑滿足給定的經過葉子結點的順序.不能的話輸出-1,否則輸出這條路徑.\(n <= 1e5\).

​ \(lca\) 樹上問題.

​ 我們發現直接按題意模擬是可以通過時間複雜度的,因為每條邊最多走兩次,所以最多走\(2n - 2\)條邊.所以我們按給定的葉子結點的順序求出相鄰兩個葉子結點的\(lca\).然後暴力條父親就好了,記得記錄一下邊的經過次數.

#include using namespace std;

inline long long read()

const int n = 1e5 + 5;

int n, cnt, num;

int id[n], dep[n], fa[n][21], head[n], tmp_ans[n * 10], ans[n * 10], in_edge[n];

struct edge e[n << 1];

void add(int x, int y)

void get_tree(int x, int fa)

if(!tag) num ++;

}void make_fa()

int lca(int x, int y)

int main()

get_tree(1, 0); make_fa();

int last = 1; tot = 0;

for(int i = 1, x, lca;i <= num + 1; i++) }

for(int i = 2;i <= cnt; i++) ans[++ tot] = tmp_ans[i];

ans[++ tot] = lca;

tmp = x; cnt = 0;

while(tmp != lca) }

for(int i = cnt;i >= 1; i--) ans[++ tot] = tmp_ans[i];

last = x;

} for(int i = 1;i <= tot; i++) printf("%d ", ans[i]);

fclose(stdin); fclose(stdout);

return 0;

}

​ 題目鏈結

​ 題目大意:給定\(n\)數\(a\)和\(n\)個數\(b\),求\(a > b\)的對數 - \(b > a\)的對數恰好等於\(k\)的方案數.\(n <= 2000\),答案對\(1e9 + 9\)取模.保證每個\(a, b\)都不相等.

​ 首先我們可以得到\(a > b\)的對數是\(\frac \).然後我們對\(a, b\)從小到大排序.

​ \(f[i][j]\)表示前\(i\)個\(a\),欽定有\(j\)對\(a > b\)的方案數,那麼dp轉移方程就是:\(f[i][j] = f[i - 1][j] + f[i - 1][j - 1] * (g[i] - (j - 1))\).

​ 為什麼是欽定不說恰好呢?假設當前所有\(a_i\)都大於\(b\),那麼是無法恰好選出\(j\)對的,因為所有的\(a_i\)都可以與其他的\(b\)形成\(a > b\),欽定的意思是強制選取\(j\)對,其他的不管,這樣之後求\(h[j]\)的時候會乘上\((n - j)!\),求出來的\(h[j]\)才是正確的.

​ \(g[i]\)表示有多少個\(b\)小於\(a_i\).這個轉移方程的含義就是"第\(i\)個數\(a_i\)沒有形成\(a > b\) + 第\(i\)個數\(a_i\)形成了\(a > b\)並且這個\(b\)前\(j - 1\)對\(a > b\)中沒有出現過 ".

​ \(h[i]\)表示至少有\(i\)對\(a > b\)的方案數(這裡也可以說是欽定\(i\)對\(a > b\),其他的不管的方案數),那麼可以得到:\(h[i] = f[n][i] * (n - i)!\).剩下\(n - i\)個數隨便排列,可能形成\(1\)到\(n - i\)對新的\(a > b\).(這樣算出的\(h[i]\)是有重複方案的對吧)

​ \(ans[i]\)表示恰好有\(i\)對\(a > b\)的方案數,我們可以發現它和\(h[i]\)的關係:\(h[i] = \displaystyle \sum_^ c_^ ans[j]\).重新看\(h[i]\)的定義:至少有\(i\)對\(a > b\)的方案數.那麼我們就要把所有\(j >= i\)的\(ans[j]\)統計到\(h[i]\)裡面,並且要算上重複的部分,也就是在乘上\(c_^\)(因為欽定了\(i\)對嘛)..

​ 然後我們把\(ans[i]\)移到一邊:\(ans[i] = h[i] - \displaystyle \sum_^ c_^ ans[j]\).然後倒推就可以了.時間複雜度\(o(n ^ 2)\).

#include using namespace std;

inline long long read()

const int n = 2005, mod = 1e9 + 9;

int n, k, num;

int a[n], b[n], g[n], h[n], fac[n], ans[n], inv[n], f[n][n];

void make_pre()

int c(int n, int m)

int main()

num = (n + k) / 2;

for(int i = 1;i <= n; i++) a[i] = read();

for(int i = 1;i <= n; i++) b[i] = read();

sort(a + 1, a + n + 1); sort(b + 1, b + n + 1);

for(int i = 1;i <= n; i++)

for(int j = 1;j <= n; j++)

if(a[i] > b[j]) g[i] ++;

else break;

for(int i = 0;i <= n; i++) f[i][0] = 1;

for(int i = 1;i <= n; i++)

for(int i = 0;i <= n; i++)

h[i] = 1ll * f[n][i] * fac[n - i] % mod;

for(int i = n;i >= num; i--)

printf("%d", ans[num]);

return 0;

}

考試總結 CQOI2017 考試總結

再奮鬥一年,爭取ak noip2016 cqoi2017 這是去年我立的flag。看考場,電腦挺快,而且配置和評測機一樣,可以放心的在自己的電腦上卡常測試啦,好評。碼了一道fft的題,沒網只好拷著回家交,鍵盤蜜汁小,enter佔據了兩行,旁邊還有關機按鈕。座位安排奧妙重重,和巴蜀dyf大神坐在一起。...

MBA考試總結

終於考完了 mba入學統考,兩年來參加了兩次,感覺還是挺辛苦和有壓力的。第一年沒有通過是因為之前了解太遲,大概準備了 20天左右,最後還是功成垂敗。09年其實也一直沒有心情複習的,逼到最後的 20天,狠了一把勁,還是狠狠的複習了幾天,貌似今年應該可以通過了。總結經驗如下 1 如果你決定去做一件事,請...

2016 7 14考試總結。

今天的考試,總的來說不難,但是考得很差,簡直 從中暴露出對知識的掌握不牢固,練習不夠等問題。1.求 方程x1 2x2 nxn m的所有非負整數解 x1,x2,xn 的個數。這個題目在加上取餘運算後就是乙個貨幣系統的問題。也就是揹包。難以接受自己連這是個揹包問題都沒看出來。3 2.其實邪狼王的貪婪也很...