為了慶祝noi的成功開幕,主辦方為大家準備了一場壽司晚宴。小g和小w作為參加noi的選手,也被邀請參加了壽司晚宴。
在晚宴上,主辦方為大家提供了n−1種不同的壽司,編號1,2,3,⋯,n-1,其中第種壽司的美味度為i+1(即壽司的美味度為從2到n)。
現在小g和小w希望每人選一些壽司種類來品嚐,他們規定一種品嚐方案為不和諧的當且僅當:小g品嚐的壽司種類中存在一種美味度為x的壽司,小w品嚐的壽司中存在一種美味度為y的壽司,而x與y不互質。
現在小g和小w希望統計一共有多少種和諧的品嚐壽司的方案(對給定的正整數p取模)。注意乙個人可以不吃任何壽司。
2<=n<=500,p<=1e9
把乙個數從它的質因子角度來考慮,對於x,如果x的質因子均不在集合1中,則可以放入集合2中,以此類推
於是我們得到乙個初始的,對於n<=30的狀壓dp:設dp[i][s1][s2]][s2]為當前選到第i個數,集合1的質因子狀態為s1,集合2的質因子狀態為s2時的方案數
轉移顯然,考慮加入第i個數時
\[dp[i][s1|p[i]][s2]+=dp[i-1][s1][s2] (s2\&p[i]==0)
\]\[dp[i][s1][s2|p[i]]+=dp[i-1][s1][s2] (s1\&p[i]==0)
\]其中p[i]表示i的質因子集合
發現這個東西其實可以滾動一下,把第一維陣列空間省了,然後s1,s2倒著列舉即可
考慮n<=500的情況,事實上我們並不需要對500以內的質因子都狀壓,因為乙個數至多有1個22以上的質因子,所以只需狀壓sqrt(n)以內的小因子,對於大因子分開討論dp進去就行
具體的來說,我們記a[i].first為i的大因子,若i所有的因子都<22,則first=1,記a[i].second為i的質因子集合
在dp的時候 所有大因子相同的數,只能放進乙個集合中,所以考慮按照大因子的大小排個序,這樣就可以把所有大因子相同的數放在一起算
考慮在dp過程中,仍然記dp[s1][s2][s2]為小因子集合為s1,s2的方案數,對於一段大因子相同的數,我們在進入這段時把dp拷貝出來,記作g1,g2,g1[s1][s2]表示這段數都放在集合1裡,小因子狀態s1,s2時的方案數,g2同理
\[g1[s1|a[i].sec][s2]+=g1[s1][s2](s2\&a[i].sec==0)
\]\[g2[s1][s2|a[i].sec]+=g2[s1][s2](s1\&a[i].sec==0)
\]然後在這一段結尾的時候,把這一段的g1和g2合併回到dp裡去
注意到在合併前,dp[s1][s2]表示這一段都沒選前,狀態為s1,s2時的方案數
然後由於g1,g2在拷貝dp時用的都是dp[s1][s2],所以在g1,g2中都有這個「整段沒選前」的方案數,所以合併起來時要減掉,即
\[dp[s1][s2]=g1[s1][s2]+g2[s1][s2]-dp[s1][s2]
\]最後統計答案就
\[ans=\sum_\sum_dp[s1][s2]
\]即可。注意取模。看一些大佬存dp時候沒開longlong,不知道是不是洛谷題面的鍋,題面的模數取值是1e10,實際上好像是1e9
最後上**
#includeusing namespace std;
const int prime[8]=;
#define sec second
#define fir first
typedef long long ll;
ll g[4][1<<9][1<<9],dp[1<<9][1<<9];
int bin[30];
paira[510];
int n;
ll p;
#define rep(i,x,y) for (int i=x;i<=y;i++)
#define res(i,x,y) for (int i=x;i>=y;i--)
void prework()
a[i].fir=x1;
}sort(a+2,a+1+n);
}void add(ll &x,ll y)
int main()
res(s1,255,0)
res(s2,255,0)
if ((i==n) || (a[i].fir!=a[i+1].fir) || (a[i].fir==1))}}
ll ans=0;
rep(s1,0,255) rep(s2,0,255)
if (!(s1&s2) && dp[s1][s2]) add(ans,dp[s1][s2]);
printf("%lld\n",ans);
return 0;
}
洛谷P2150 壽司晚宴
考慮暴力,當n 30 時,素數有2 3 5 7 11 13 17 19 23 29,一共10個,狀壓dp可行,f i j 表示每個人選數的狀態,然後暴力轉移就好了,複雜度o 22n 然後我就想不出來了 有乙個常用到的性質就是,對於任何乙個數字 x 其大於x 的約數只能有乙個或者沒有,利用這個性質,可...
p2150 NOI2015 壽司晚宴
傳送門 分析 我們發現對於大於 sqrt n 的數每個數最多只會包含乙個 所以我們把每個數按照大質數的大小從小到大排序 我們知道對於一種大質數只能被同乙個人取 所以f1表示被a取,f2表示被b取 最終答案就是這兩個的答案減去啥都不去的答案 因為啥都不去會被重覆記錄兩次 對於小質數則直接狀壓轉移即可 ...
洛谷 P1955 NOI2015 程式自動分析
目錄 傳送門 首先看到這種沙雕範圍 109109 直接選擇離散化,然後貌似就是簡單直接的並查集了 我們先將相等關係的 x x y role presentation y y進行合併,然後看不相等關係中的 x x y role presentation y y,如果他們兩個的祖先是一樣的,也就是之前已...