NOI2015 壽司晚宴

2022-05-09 10:45:12 字數 2457 閱讀 7121

嘟嘟嘟

昨天模擬t2 lba和dukelv都說和這題特別像(然而他倆還是沒做出來hhhh),我今天一看,果不其然,大體思路都一樣。

但自認為這題比模擬題要難一些,自己也是因為沒有徹底理解浪debug了半天,導致費了很長時間。

當\(n \leqslant 30\)時,因為質數只有最多10個,所以可以狀壓每乙個數的質因數,令\(dp[i][s_1][s_2]\)表示前\(i\)個數中,第乙個人選的質因數組合是\(s_1\),第二個人是\(s_2\)時的方案數,然後\(o(n * 2 ^ )\)暴力dp就ok了。

當\(n \leqslant 500\)時,上述做法顯然不行,但是小於等於\(\sqrt\)的質數最多只有8個,而對於每乙個數大於\(\sqrt\)的質因數最多只有1個。所以我們可以把擁有同乙個大質數的數放到一塊兒,然後按這一堆裡面只有乙個人能選的規則進行dp。

那麼上述轉移方程就不好用了。所以建兩個臨時dp方程\(f1[i][s_1][s_2], f2[i][s_1][s_2]\)分別表示只有第乙個人和第二個人選的時候的方案數。對於當前的乙個數的質因數情況\(s\),$$f1[i][s_1 | s][s_2] += f1[i - 1][s_1][s_2] (s & s_2 = 0)$$$$f2[i][s_1][s_2 | s] += f2[i - 1][s_1][s_2] (s & s_1 = 0)$$因為\(f_1\)和\(f_2\)只會從內部轉移,不會出現對方選的情況,也就符合這些數只能有乙個人選的規則了。

然後我們在把這兩個陣列合併到原來的dp方程上:$$dp[i][s_1][s_2] = f1[m][s_1][s_2] + f1[m][s_1][s_2] - dp[i - 1][s_1][s_2]$$這個有點像樹上兩點的路徑長,要減去lca的貢獻。

很多題解都是把兩種大質數和小質數何在一塊寫的,但是因為拿到模擬題我就是分開寫的,所以這題我也分開了。

(第一維用滾動陣列優化一下)

#include#include#include#include#include#include#include#include#include#includeusing namespace std;

#define enter puts("")

#define space putchar(' ')

#define mem(a, x) memset(a, x, sizeof(a))

#define in inline

typedef long long ll;

typedef double db;

const int inf = 0x3f3f3f3f;

const db eps = 1e-8;

const int maxn = 505;

inline ll read()

inline void write(ll x)

ll mod;

int n;

in ll inc(ll a, ll b)

const int p[8] = ;

vectorv[maxn];

in void solve(int n)

ll dp[2][(1 << 8) + 2][(1 << 8) + 2];

ll f1[2][(1 << 8) + 2][(1 << 8) + 2], f2[2][(1 << 8) + 2][(1 << 8) + 2];

int main()

for(int j = 0; j < (1 << 8); ++j)

for(int k = 0; k < (1 << 8); ++k) dp[o ^ 1][j][k] = 0;

}for(int i = 23; i <= n; ++i)

if(v[i].size())

int p = o;

for(int h = 0; h < (int)v[i].size(); ++h, p ^= 1)

for(int j = 0; j < (1 << 8); ++j)

for(int k = 0; k < (1 << 8); ++k)

f1[p ^ 1][j][k] = f1[p][j][k], f2[p ^ 1][j][k] = f2[p][j][k];

}for(int j = 0; j < (1 << 8); ++j)

for(int k = 0; k < (1 << 8); ++k)

dp[o][j][k] = inc(inc(f1[p ^ 1][j][k], f2[p ^ 1][j][k]), mod - dp[o ^ 1][j][k]);

o ^= 1;

}ll ans = 0;

for(int i = 0; i < (1 << 8); ++i)

for(int j = 0; j < (1 << 8); ++j)

if(!(i & j)) ans = inc(ans, dp[o ^ 1][i][j]);

write(ans), enter;

return 0;

}

NOI 2015 壽司晚宴

description 為了慶祝 noi 的成功開幕,主辦方為大家準備了一場壽司晚宴。小 g 和小 w 作為參加 noi 的選手,也被邀請參加了壽司晚宴。在晚宴上,主辦方為大家提供了 n 1 種不同的壽司,編號 1,2,3,n 1,其中第 i 種壽司的美味度為 i 1 即壽司的美味度為從 2 到 n...

NOI 2015 壽司晚宴

4197 noi2015 壽司晚宴 time limit 10 sec memory limit 512 mb submit 813 solved 508 submit status discuss description 為了慶祝 noi 的成功開幕,主辦方為大家準備了一場壽司晚宴。小 g 和小 ...

NOI2015 壽司晚宴

題目 這是一篇需要龜速乘的思博題解 我們考慮一下 n leq 30 的睿智暴力,顯然質因數個數少得一批,互質的條件又等價於沒有公共的質因子,所以我們直接狀壓質因子,dp i s 1 s 2 表示前 i 個數考慮完了,第乙個人選擇的質因子狀態為 s 1 第二個人選擇的質因子狀態為 s 2 轉移的話就考...