

【题解】寿司晚宴
source link: https://blog-e.tk/2021/05/27/%E9%A2%98%E8%A7%A3-%E5%AF%BF%E5%8F%B8%E6%99%9A%E5%AE%B4/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

介绍一种 O(n×38) 的做法,目前是所有非打表代码中的最优解,其实只是把其他题解中的算法优化了一下。
这题的暴力有很多种,在此只介绍可以优化成正解的暴力。
两个数互质,等效于他们没有共同的质因子,所以只需把每个数都分解质质因数,如下dp:
- 状态:dp[s1][s2] 表示考虑前 i 个数(i被滚动掉了),小 G 选的数的包含的质因数集合为 s1,小 W 的质因数集合为 s2 的情况数。
- 转移: 假设 faci 表示 i 的质因数集合,则有转移。 dp[s1|faci][s2]←dp[s1][s2]+dp[s1|faci][s2] (faci&s2=0)dp[s1][s2|faci]←dp[s1][s2]+dp[s1][s2|faci](faci&s1=0)
- 答案: ∑s1,s2∈{x|x为n以内质数}dp[s1][s2] (s1&s2=0))
虽然这个状态在 n≤30 时显然可以优化,但是优化了的话就没法做更大范围了,复杂度 O(n×220)。
n≤500,则小于 n 的质数大概有一百个了,仿佛就无法状压了。但经过仔细观察(看题解),发现每个数只可能有一个大于 √500=19 的质因数,也就是说,每个数除了这个最大质因数之外,剩下的质因数都小于19。
小于 19 的质因数只有 8 个,不难状压,所以我们只要考虑如何排除那些大质因数的干扰。
考虑将这些数按其大质因数排序,则大质因数相同的一个连续段中的每个数要么只被小 G 选或不被选,要么只被小 W 选或不被选。
考虑如下 dp:
- dp[s1][s2] 含义与上面的差不多,只不过这里的 s1,s2 只状压了前 8 个质数的状态。
- 每次进入一个新的连续段,把 dp 中的值复制到 t1,t2 中。
- 用 t1[s1][s2] 表示这个连续段中的数只被小 G 选或不被选的情况数
- 用 t2[s1][s2] 表示这个连续段中的数只被小 W 选或不被选的情况数
- 转移: t1[s1|faci][s2]←t1[s1|faci][s2]+t1[s1][s2] (faci&s2=0)t2[s1][s2|faci]←t2[s1][s2|faci]+t2[s1][s2](faci&s1=0)
- 这个连续段结束之后,再用 t1,t2 中的值更新 dp 值: dp[s1][s2]←t1[s1][s2]+t2[s1][s2]−dp[s1][s2] 为什么要减去 dp[s1][s2] 呢?因为这一段中所有数都不选的情况被算了两次(t1,t2 各一次)。
截止目前,算法复杂度还是 O(n×48) 的,但是不难发现对于一个合法状态,是要求 s1,s2 交为空的。因此真正有用的状态数只有 38 量级。 所以我们可以如下枚举 s1 和 s2:
int ALL=1<<8;
for(int s1=ALL-1;~s1;s1--){//因为是滚动数组,所以集合必须从大到小枚举
int tmp=(ALL-1)^s1;//s2 必定是 tmp 的子集
for(int s2=tmp;s2;s2=(s2-1)&tmp)
//blabla...
//单独处理 s2=0 的情况
}
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
typedef pair<int,int> pi;
const int MXPRI=8;
const int ALL=1<<MXPRI;
const int MXN=505;
const int pri[]={2,3,5,7,11,13,17,19};
int n,p,dp[ALL][ALL],t1[ALL][ALL],t2[ALL][ALL];
pi arr[MXN];
inline int mod(int x){return x<p?x:x-p;}
int main(){
scanf("%d%d",&n,&p);
for(int i=2,j;i<=n;i++)
for(arr[i].fi=i,j=0;j<MXPRI;j++)
while(arr[i].fi%pri[j]==0)
arr[i].fi/=pri[j],arr[i].se|=1<<j;
sort(arr+2,arr+n+1);
t1[0][0]=1;
for(int i=2;i<=n;i++){
if(arr[i].fi==1 || arr[i].fi!=arr[i-1].fi)
for(int s1=ALL-1;~s1;s1--){
int tmp=(ALL-1)^s1;
for(int s2=tmp;s2;s2=(s2-1)&tmp)
t1[s1][s2]=t2[s1][s2]=dp[s1][s2]=mod(p-dp[s1][s2]+mod(t1[s1][s2]+t2[s1][s2]));
t1[s1][0]=t2[s1][0]=dp[s1][0]=mod(p-dp[s1][0]+mod(t1[s1][0]+t2[s1][0]));
}
for(int s1=ALL-1,fac=arr[i].se;~s1;s1--){
int tmp=(ALL-1)^s1;
for(int s2=tmp;s2;s2=(s2-1)&tmp){
if(!(fac&s2))t1[s1|fac][s2]=mod(t1[s1|fac][s2]+t1[s1][s2]);
if(!(fac&s1))t2[s1][s2|fac]=mod(t2[s1][s2|fac]+t2[s1][s2]);
}
t1[s1|fac][0]=mod(t1[s1|fac][0]+t1[s1][0]);
if(!(fac&s1))t2[s1][fac]=mod(t2[s1][fac]+t2[s1][0]);
}
}
int ans=0;
for(int s1=ALL-1;~s1;s1--){
int tmp=(ALL-1)^s1;
for(int s2=tmp;s2;s2=(s2-1)&tmp)
ans=mod(ans+mod(p-dp[s1][s2]+mod(t1[s1][s2]+t2[s1][s2])));
ans=mod(ans+mod(p-dp[s1][0]+mod(t1[s1][0]+t2[s1][0])));
}
printf("%d\n",ans);
return 0;
}
作者:@ethan-enhe
本文为作者原创,转载请注明出处:本文链接
阅读量 75
v1.4.4
Recommend
-
124
相关专题:2017第四届世界互联网大会新浪科技讯12月3日晚间消息,在丁磊饭局之后,今夜乌镇第二场大佬饭局开启,京东刘强东和美团点评王兴再组局,腾讯马化腾、小米雷军等再次现身。从一张晚宴合影来看,除马化腾和雷军之外,出席“东兴局”的还有高瓴
-
33
今天,博鳌——这座沉默了千百年的渔港小镇,成为亚洲焦点。世界各地嘉宾纷至沓来,共赴“东方之约”。而马云又一次成为焦点中的焦点。今日晚间,阿里巴巴董事局主席马云与IMF总裁拉加德展开对话并同时进行晚宴。央视财经记者在现场见证了,这场晚宴的豪华
-
35
新浪财经讯今日晚间阿里巴巴董事局主席马云将与IMF总裁拉加德展开对话并同时进行晚宴。由于该场对话为定向邀请制,因此许多参与博鳌论坛的嘉宾和媒体都难以进入对话现场,堵在门外。据悉,本次晚宴的座上宾包括了联合国前秘书长潘基文夫妇、香港特别行政区
-
49
今日晚间阿里巴巴董事局主席马云将与IMF总裁拉加德展开对话并同时进行晚宴。由于该场对话为定向邀请制,因此许多参与博鳌论坛的嘉宾和媒体都难以进入对话现场,堵在门外。
-
28
在郎朗结婚的晚宴上,郎朗与Gina Alice即兴四手联弹,最后新娘还转头亲了一下郎朗~热度排序 时间排序...
-
15
来源:梨视频【楚商大会欢迎晚宴,马云抓紧时间吃,雷军玩手机】12月19日,在第四届楚商大会欢迎晚宴上,浙江商会总会会长马云、全国工商联副主席雷军、楚商联合会会长陈东升、川商总会会长刘永好等大佬齐聚,看看大佬们吃饭的时候都在干什么。12月20
-
25
深圳一国企晚宴喝掉16万茅台,官方:涉事董事长被免职
-
7
Nova 私享晚宴——云集钱塘,洞见新风向7 月 24 日晚,由 Nova Club 个人会员俱乐部和麒麟加密区块共同举办的杭州家宴圆满举行。席间,在杭州区块链加密周末的盛典氛围下,会员们结合最新的政策监管导向,探求 Defi 与 Cefi 的有机结合,将金融衍...
-
7
国王的晚宴 King's dinner Bob Jiang 2020-07-09 作者:Ron Jeffries 译者:年志君 (微信公众号:敏捷家) 这个小故事根据资源、质量、范围和时间的关键度量变量,来描述了...
-
7
马斯克在华首日晚宴费用或曝光:22人消费4.5万左右 评论(6)...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK