首页 > 其他分享 >P2150 [NOI2015] 寿司晚宴

P2150 [NOI2015] 寿司晚宴

时间:2024-08-05 22:07:23浏览次数:8  
标签:f1 f2 P2150 寿司 质数 NOI2015 data ll define

思路:

注意到对于每个数,其 \(>19\) 的质因数最多只有 \(1\) 个,称为大质数;对于 \(\le 19\) 的质因数有 \(8\) 个,称为小质数

设第 \(i\) 个数的小质数集合为 \(h_i\)。

那么考虑对于所有数按照大质数从小到大排序,那么对于大质数相同的一段,只能放在两个集合中的一个。

考虑状态压缩 \(dp\),定义 \(dp_{S_1,S_2}\) 表示对于取完 \(i\)(可以滚动数组) 个数后第一/二个集合的小质数集合,\(f1_{S_1,S_2}\) 表示这一段的数都放在第一个集合的方案数,\(f2_{S_1,S_2}\) 表示这一段的数都放在第二个集合的方案数。

则状态转移方程为(首先要满足 \(S_1\) 与 \(S_2\) 没有交集,即 \(S_1 \operatorname{and} S_2 = 0\)):

\[f1_{S_1 \operatorname{or} data_i,S_2} += f1_{S_1,S_2} [S_2 \operatorname{and} h_i = 0] \]

\[f2_{S_1,S_2 \operatorname{or} data_i} += f1_{S_1,S_2} [S_1 \operatorname{and} h_i = 0] \]

\[dp_{S_1,S_2} = f1_{S_1,S_2} + f2_{S_1,S_2} - dp_{S_1,S_2} \]

因为 \(f1\) 和 \(f2\) 都可以不取这一段的数,那么 \(dp_{S_1,S_2}\) 就被算了两次,减掉即可。

时间复杂度为 \(O(n2^{16})\)。

完整代码:

#include<bits/stdc++.h>
#define Add(x,y) (x+y>=mod)?(x+y-mod):(x+y)
#define lowbit(x) x&(-x)
#define pi pair<ll,ll>
#define pii pair<ll,pair<ll,ll>>
#define iip pair<pair<ll,ll>,ll>
#define ppii pair<pair<ll,ll>,pair<ll,ll>>
#define fi first
#define se second
#define full(l,r,x) for(auto it=l;it!=r;it++) (*it)=x
#define Full(a) memset(a,0,sizeof(a))
#define open(s1,s2) freopen(s1,"r",stdin),freopen(s2,"w",stdout);
using namespace std;
typedef double db;
typedef unsigned long long ull;
typedef long long ll;
bool Begin;
const ll N=505,M=8,S=(1ll<<M);
inline ll read(){
    ll x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-')
          f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        x=(x<<1)+(x<<3)+(c^48);
        c=getchar();
    }
    return x*f;
}
inline void write(ll x){
	if(x<0){
		putchar('-');
		x=-x;
	}
	if(x>9)
	  write(x/10);
	putchar(x%10+'0');
}
struct Node{
	ll x;
	ll data;
	bool operator<(const Node&rhs)const{
		return x<rhs.x;
	}
}a[N];
ll n,x,ans,mod;
ll dp[S][S],f1[S][S],f2[S][S];
ll P[]={2,3,5,7,11,13,17,19};
bool End;
int main(){
	n=read(),mod=read();
	for(int i=2;i<=n;i++){
		x=i;
		for(int j=0;j<8;j++){
			if(x%P[j]==0){
				a[i].data|=(1ll<<j);
				while(x%P[j]==0)
				  x/=P[j];
			}
		}
		if(x!=1)
		  a[i].x=x;
	}
	dp[0][0]=1;
	sort(a+2,a+n+1);
	for(int i=2;i<=n;i++){
		if(!a[i].x||a[i].x!=a[i-1].x){
			for(int X=0;X<S;X++)
			  for(int Y=0;Y<S;Y++)
			    f1[X][Y]=f2[X][Y]=dp[X][Y];
		}
		for(int X=S-1;X>=0;X--){
			for(int Y=S-1;Y>=0;Y--){
				if(X&Y)
				  continue;
				if((a[i].data&Y)==0)
				  f1[X|a[i].data][Y]=Add(f1[X|a[i].data][Y],f1[X][Y]);
				if((a[i].data&X)==0)
				  f2[X][Y|a[i].data]=Add(f2[X][Y|a[i].data],f2[X][Y]);
			}
		}
		if(i==n||a[i].x!=a[i+1].x||!a[i].x){
			for(int X=0;X<S;X++)
			  for(int Y=0;Y<S;Y++)
			    dp[X][Y]=(f1[X][Y]+f2[X][Y]-dp[X][Y]+mod)%mod;			
		}
	}
	for(int X=0;X<S;X++)
	  for(int Y=0;Y<S;Y++)
		ans=Add(ans,dp[X][Y]);
	write(ans);
	cerr<<'\n'<<abs(&Begin-&End)/1048576<<"MB";
	return 0;
}

标签:f1,f2,P2150,寿司,质数,NOI2015,data,ll,define
From: https://www.cnblogs.com/rgw2010/p/18344137

相关文章

  • 「清新题精讲」P2150 [NOI2015] 寿司晚宴
    P2150[NOI2015]寿司晚宴Statement给定\(n-1\)个数分别为\(2\simn\),从中选出交集为空的两个集合\(A,B\)(集合的并集不必须为\(\{2,\dots,n\}\),且集合可为空)使得不存在\(a\inA,b\inB\)满足\((a,b)\ne1\)(即任意两个数均互质),将方案数对\(p\)取模后输出。\(2\len\le......
  • [Ynoi2015] 纵使日薄西山
    按照题目来模拟,假设\(a_x\)为最大的,那么任意时刻不可能选中\(a_{x-1}\)或者\(a_{x+1}\)来操作的然后就可以发现,我们选出的数一定是不相邻的,也就是说,我们每次在还可以选择的数中找出最大的数(满足此条件下下标最小),并且把相邻的两个数标记为不可选择,一直重复这个过程直到为\(0\);显然......
  • P2178 [NOI2015] 品酒大会 题解(评分:8.0)(2024.2.23)
    前言"I'mfree."做法与题解区都不同,虽然麻烦,但是毕竟复杂度是对的,而且想法很自然,还是写一写吧!Solution题意:给定长为\(n\)的字符串\(s\)和长为\(n\)的数组\(A\),对于每个\(r\),求满足\(\text{LCP}(\text{Suffix}(x),\text{Suffix}(y))\ger,x<y\)的数对\((x,y)\)数......
  • P2168 [NOI2015] 荷马史诗
    原题链接题解1.该题等价于构建一颗k叉树,每个叶子节点都有一个权值\(leaf_i\),树的权值为\(\sum_{1}^{n}leaf_i\),在使树的权值尽可能小的情况下,使最深的叶子节点的深度也尽可能小,即使数的高度尽可能小这个叫做哈夫曼树2.构建过程如下:每次从队列中取出\(k\)个节点,然后把他......
  • 洛谷题单指南-集合-P1955 [NOI2015] 程序自动分析
    原题链接:https://www.luogu.com.cn/problem/P1955题意解读:要判断约数条件是否可以同时满足,主要是要判断不相等的情况。解题思路:对于相等的条件,直接进行集合合并即可;对于不相等的条件,判断两者是否属于同一个集合,如果形成矛盾,则条件不能成立。由于i,j的范围至10^9,定义并查集如果......
  • 华为OD机试Java - 转盘寿司
    转盘寿司前言:本专栏将持续更新互联网大厂机试真题,并进行详细的分析与解答,包含完整的代码实现,希望可以帮助到正在努力的你。关于大厂机试流程、面经、面试指导等,如有任何疑问,欢迎联系我,wechat:steven_moda;email:[email protected];备注:CSDN。题目描述寿司店周年庆,正在举办......
  • P3242 [HNOI2015] 接水果 抽象做法
    好吧好吧,自己做出来的第一道整体二分。省流:理解能力比较强的话直接拖到最后看算法流程吧。下面我们称输入时盘子的权值为“盘子的大小”,与文中使用的算法给盘子的赋权区分开。一堆询问第\(k_i\)小,考虑整体二分。先考虑外部过程。上整体二分板子,每次二分\(mid\),形象地把盘......
  • p2150-solution
    P2150Solutionlink首先两人选的数两两互质相当于两人的质因数集合无交。先考虑\(n\le30\):由于\(30\)内的质因只有\(10\)个,我们考虑状压\(dp\)。设\(dp_{i,S1,S2}\)表示考虑到第\(i\)个数,G选了质因数集合\(S1\),W选了质因数集合\(S2\)的方案数。刷表转移:\[d......
  • P2178 [NOI2015] 品酒大会
    题意简述定义后缀\(p,q\)是\(r\)相似的当且仅当\(\forall1\lei\ler,s_{p+i-1}=s_{q+i-1}\)。对于每一个\(0\ler<n\),求出:有多少对\(r\)相似的后缀。每个后缀有权值\(a_i\),求在所有\(r\)相似的后缀对\((p,q)\)中\(a_p\cdota_q\)的最大值。若不存在则答案为......
  • 寿司晚宴
    这道题目挺综合的。。首先看到互质,可以知道这是约数一类的题目,而约数一类的题目,可以考虑分解质因数所以我们给每个数分解质因数,我们发现,要让两个人选的数字全部互质,那么有一个显然的充要条件:甲选的数字的质因数集合和乙选的数字的质因数集合没有交集(要么从单个数考虑,要么从整体......