1014下午考試

2022-05-07 17:36:13 字數 3300 閱讀 3617

​ 題目大意:

​ 有乙個\(n*m\)的矩陣,矩陣的每個位置上可以放置乙個數。對於第i行,第i行的差異定義為該行的最大數和最小數的差。乙個矩陣的差異,定義為矩陣中每一行差異的最大值。現在給定k個數v[1..k],問:從這k個數中選\(n*m\)個數放入矩陣,能夠得到的矩陣的差異最小值是多少。

​ n * m <= k <= 100000, n, m <= 1000,0<= v[i] <= 10^9

​ 二分。

​ 就是二分的板子題,先對每個數排序,然後二分矩陣差異最小值,貪心的判斷是否可以選出n個長度為m的連續子段。

#include #define mid ((l + r) >> 1)

using namespace std;

inline long long read()

const int n = 1e5 + 5, inf = 1e9;

int k, n, m, ans;

int a[n], vis[n];

int check(int s)

else

if(tmp == m)

}if(tag == 0 && tmp == m) res ++;

}return res >= n;

}int main()

printf("%d", ans);

fclose(stdin); fclose(stdout);

return 0;

}

​ 題目大意:

​ 給定乙個長度為n的序列v[1..n],現在要將這個序列分成k段(每段都不能為空),定義每一段的權值為該段上的所有數的或和。定義整個序列的權值為每段權值的和。問:這個序列的最大權值為多少。

​ k <= n <= 2000,1<= v[i] <= 5 *10^5

​ 線性dp。

​ 考場上想出來60分的做法:

​ \(f[i][j]\)表示前\(i\)個數分成\(j\)段的最大權值,那麼轉移方程就是:\(f[i][j] = max(f[i][j], f[l][j - 1] + or[l + 1][i])\)。

​ 複雜度\(o(n ^ 3)\)。

​ 考慮優化一下,或和從0變到10^6大概需要20次,如果說沒變,我們只需要取沒變的這一段\(f\)值最大的乙個就好了。因為\(or\)隨著長度變小單調不公升,\(f\)隨著長度變大單調不降,所以這一段最後乙個點就是斷點。所以我們可以與處理出斷點在哪,第三層迴圈直接列舉這些斷點就好了。

​ 複雜度\(o(n^2logn)\)。

#include using namespace std;

inline long long read()

const int n = 2005;

int n, k;

long long a[n], aor[n][n], f[n][n];

vector v[n];

int main()

​ 題目大意:

​ 有一棵k+1層的滿二叉樹,那麼該樹有2^k 個葉子節點。給定n個機械人(n=2^k),編號從1—n,編號為i的機械人的權值為v[i]。我們現在要將這n個機械人分別放置在這n個葉子節點上,每個葉子節點放且只能放乙個機械人。葉子節點的權值為該葉子節點上的機械人的權值。非葉子節點的權值定義為該樹中編號最大的機械人的權值。每個非葉子節點除了權值以外,還有乙個魔法值,該點的魔法值為其左右兒子節點的權值的乘積。整棵樹的魔法值定義為非葉子節點的魔法值的和。問:將這n個機械人隨機地放在這n個葉子節點上,樹的魔法值的期望為多少。

​ 假設答案為乙個不可約分數p/q,則輸出在模1e9+7意義下的p* (q^-1)模1e9+7的值。k <= 18。

​ 組合數 + 推式子

​ 我們假設當先要合併的點高度為d,左子樹權值為x,右子樹權值為y,x > y;

​ 那麼貢獻是這個:\(c(y - 1, 2^d - 1) * c(x - 2 ^ d - 1, 2^d - 1) * v[x] * v[y] * (n - 2^)! * 2 * 2^ * 2^d! * 2^d!\)。

​ 解釋一下:

​ 高度為d的二叉樹節點的子樹中有\(2 ^ d\)個節點,要從比\(y\)小的數裡面選出\(2^d - 1\)個數,順序不同方案也不同,所以是:\(c(y - 1, 2 ^ d - 1) * 2 ^ d!\)。

​ 除去\(y\)的子樹中的節點後,要從比\(x\)小的數裡面選出\(2^d - 1\)個數,順序不同方案也不同,所以是:\(c(x - 2^d - 1, 2 ^ d - 1) * 2 ^ d!\)。

​ 除去\(x, y\)的所有節點後,剩下的數隨便排,所以是:\((n - 2 ^ d - 2^d)! = (n - 2^)!\)。

​ \(x, y\)的順序可以交換,所以再乘2。

​ 當前高度為d,那麼層數就是\(k - d\)層,二叉樹這一層會有\(2 ^ \)個節點,都可以在這上面合併,所以再乘\(2 ^ \)。

​ 最後再乘上\(x, y\)的權值\(v[x], v[y]\)。

​ 複雜度\(o(kn ^ 2)\)。

​ 可以字尾和優化一下,首先原式子可以寫成:

​ \(\displaystyle \sum_ \sum_ \sum_ * a(y - 1, 2^d - 1) * a(x - 2^d - 2, 2^d - 1) * (n - 2^)! * 2^\)。

​ 還可以寫成:

​ \(\displaystyle \sum_ (n - 2^)! * 2^ \sum_ a(y - 1, 2^d - 1) \sum_ a(x - 2^d - 2, 2^d - 1)\)

​ 預處理出後面那兩坨sigema的字尾和就好了,複雜度\(o(kn)\)。

#include #define ls(o) (o << 1)

#define rs(o) (o << 1 | 1)

#define mid ((l + r) >> 1)

using namespace std;

inline long long read()

const int n = 3e5 + 5, mod = 1e9 + 7;

int k, n;

int ans, a[n];

long long fac[n], inv[n], bit[n], sum[n];

void make_pre()

int c(int x, int y)

int main()

printf("%d", 1ll * ans * inv[n] % mod);

fclose(stdin); fclose(stdout);

return 0;

}

10 9 下午 考試

t1 f i 表示不和法數大於i個的數量 f i c n ic 首先n m k n 先不考慮 用擋板法易知 ans c 即給m個果子中間再加上n 1個擋板的位置,在選n 1個 那考慮必須放乙個的情況,只要預先把m n,相當於每個籃子先放乙個 那考慮不合法數 i個,只需要預先給i個放k個,那這i個一定...

10 30 下午考試

p76 年?月?日?題目名稱 他 她 它 名稱 he she it 輸入 he.in she.in it.in 輸出 he.out she.out it.out 每個測試點時限 1 秒 1 秒 1 秒 記憶體限制 512mb 512mb 512mb 測試點數目 10 10 10 每個測試點分值 10...

4 27 下午 閱讀

預設進入系統,我們會看到這樣的字元 root localhost 其中 代表當前是 root 使用者登入,如果是 表示當前為普通使用者。我們了解linux由很多目錄檔案構成,那我們來學習第乙個 linux 命令 cd命令,cd home 解析 進入 home 目錄cd root 進入 root 目錄...