為了慶祝 noi 的成功開幕,主辦方為大家準備了一場壽司晚宴。小 g 和小 w 作為參加 noi 的選手,也被邀請參加了壽司晚宴。
在晚宴上,主辦方為大家提供了 n−1 種不同的壽司,編號 1,2,3,…,n−1,其中第 i 種壽司的美味度為 i+1 (即壽司的美味度為從 2 到 n)。
現在小 g 和小 w 希望每人選一些壽司種類來品嚐,他們規定一種品嚐方案為不和諧的當且僅當:小 g 品嚐的壽司種類中存在一種美味度為 x 的壽司,小 w 品嚐的壽司中存在一種美味度為 y 的壽司,而 x 與 y 不互質。
現在小 g 和小 w 希望統計一共有多少種和諧的品嚐壽司的方案(對給定的正整數 p 取模)。注意乙個人可以不吃任何壽司。
輸入檔案的第 1 行包含 2 個正整數 n,p,中間用單個空格隔開,表示共有 n 種壽司,最終和諧的方案數要對 p 取模。
輸出一行包含 1 個整數,表示所求的方案模 p 的結果。
3 10000
9\(2\le n\le 500\),\(0。
首先考慮最直接的狀壓dp:兩個人的選擇方案合法,當且僅當兩人各自所選編號的質因子無交集。
記\(f[i][s_a][s_b]\)表示當前選到\(i\)號數,乙個人選擇的數質因子狀態為\(s_a\),a另一人為\(s_b\)的總方案數。其中第一維可以省去。
但是500以內的質數還是很多,\(s_a\)和\(s_b\)壓不起來,怎麼做呢?
考慮每乙個數都是由若干個小於等於\(\sqrt \)的質數乘起來,再乘上乙個剩餘部分\(l\):乙個大於\(\sqrt\)的質數或者1得到。我們發現小於等於\(\sqrt\)也就是22.36的質數恰好只有8個,此時\(s\)的大小為256,是可以開得下上述陣列的。
處理出所有數包含小於根號質數的狀態,並按剩餘部分\(l\)從小到大排序。剩餘部分為1的數顯然可以按上述基礎方法直接dp。
接下來,對於剩餘部分\(l\)不為1的每一段數。我們發現,兩人不可能同時取這一段中的數——要麼a不要動,讓b自己選擇;要麼b不要動,讓a自己選擇。
所以把每一段\(l\)相同的數拉出來dp一次。記\(g_a[s_a][s_b]\)表示只讓a取這一段的方案數,\(g_b[s_a][s_b]\)同理。兩個dp是獨立分開的。列舉該段中每乙個數,看某人選了是否不會和另一人衝突,並決定選還是不選。
dp開始前\(g_a[s_a][s_b]=g_b[s_a][s_b]=f[s_a][s_b]\)。該段dp完成後,反過來把走過這一段後的資料更新回\(f\):
\(f[s_a][s_b]=g_a[s_a][s_b]+g_b[s_a][s_b]-f[s_a][s_b]\)。
注意後面要減去乙個未dp前的方案數,因為兩個\(g\)加起來時,兩人都不選的情況總共被算了2次。
從此題我們可以得到一些啟發:如果狀態壓不下,那就應該考慮能否減少狀態規模,如找到特殊的元素單獨考慮。
#include #include #include using namespace std;
const int n=505,p[9]=;
int n,mod;
int f[260][260],g[2][260][260];
inline int plu(int x,int y)
inline int mul(int x,int y)
inline void upd(int &x,int y)
inline bool in(int st,int i)
inline int bit(int i)
struct datad[n];
bool cmp(const data &a,const data &b)
} for(j=i;i=0;x--)
for(int y=all-1;y>=0;y--)
} for(int x=0;xfor(int y=0;yf[x][y]=plu(plu(g[0][x][y],g[1][x][y]),-f[x][y]);
} int ans=0;
for(int x=0;xfor(int y=0;yupd(ans,f[x][y]);
printf("%d\n",plu(ans,mod));
return 0;
}
BZOJ 4197 Noi2015 壽司晚宴
為了慶祝 noi 的成功開幕,主辦方為大家準備了一場壽司晚宴。小 g 和小 w 作為參加 noi 的選手,也被邀請參加了壽司晚宴。在晚宴上,主辦方為大家提供了 n 1 種不同的壽司,編號 1,2,3,n 1,其中第 i 種壽司的美味度為 i 1 即壽司的美味度為從 2 到 n 現在小 g 和小 w ...
bzoj4197 NOI2015 壽司晚宴
題意 有n 1 個數從 2 n 從中選出兩個集合 s 和 u 可以為 要求對於 x s,y u,都有gc d x,y 1 求方案總數 n 500 解法 狀壓dp 首先看到互質這一條件,可以想到利用質因子來判斷 很同意證明,對於乙個數 x 大於x 的質因子至多有乙個。假設存在兩個及兩個以上大於x 的質...
BZOJ4197 NOI2015 壽司晚宴
bzoj luogu 從 2 到 n 中選出兩個不相交子集使得這兩個集合中的任一對元素互質。問總方案數模 mod 的結果。n le500 首先有 30 的部分分是 n le30 考慮到 30 以內的質因數只有 10 個,因此可以狀壓 dp 即設 f s 1 s 2 表示第乙個人選出的質因數集合為 s...