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

[NOI2015] 寿司晚宴

时间:2023-12-26 22:44:37浏览次数:48  
标签:cnt 寿司 int two NOI2015 因子 MAXN 晚宴 DP

P2150 [NOI2015] 寿司晚宴

翻译一下,题目其实就是给你\(2-n\)这些数,从其中选出两个集合(可以为空),求使两个集合中的数两两互质的方案数。

那么就相当于说两个集合中的数的质因数的集合不能有重合。

先看前\(\%30\)的数据,\(n<=30\),里面的质因数不多,考虑状压\(DP\)

我们不妨设\(DP[i][S_1][S_2]\)表示在前\(i\)个数中,第一个集合的质因数集合为\(S_1\),第二个为\(S_2\)的情况下的方案数。

状态转移:(\(k\)表示第\(i\)个数的质因子集合)

\(DP[~i~][~S_1|k~][~S_2~]~=~DP[~i-1~][~S_1~][~S_2~]+DP[~i~][~S_1|k~][~S_2~]~(S_2\&k=0)\)

\(DP[~i~][~S_1~][~S_2|k~]=DP[~i-1~][~S_1~][~S_2~]+DP[~i~][~S_1~][~S2|k~]~(S_1\&k=0)\)

由于每一个\(DP[i]\)之和\(DP[i-1]\)有关,且\(DP[i][S_1][S_2]\)只会从\(DP[i-1][S_1'][S_2'](S_1>=S_1'~;~S_2>=S_2')\)转移,所以可以降维优化,将\(S_1,S_2\)倒着枚举即可。

接着我们考虑全部的数据范围。

可是,小于\(500\)的质因子太多了,状压绝对会超空间。

但是我们发现,\(500\)以内的数最多有一个质因子\(>22\)(我们称其大因子)(因为一个数\(x\)最多只有一个质因子\(>\sqrt{x}\),而\(\sqrt{500}=22\)),而小于\(22\)的质因子只有\(8\)个,满足状压。

我们先预处理,把大因子相同的放在一起,由于相同大因子的数不能放在一起,那么设置\(F_1[S_1][S_2],F_2[S_1][S_2]\),分别表示只把相同大因子放第一个集合或第二个集合的情况,状态转移方程同上。

而当相同大因子的数处理完后,要把他们合并到\(DP\)数组里,公式为:\(DP[S_1][S_2]=F_1[S_1][S_2]+F_2[S_1][S_2]-DP[S_1][S_2]\)。

之所以要减去一个\(DP[S_1][S_2]\),是因为\(F_1\)和\(F_2\)中都计算了一次相同大因子的数一个都不选的情况,需要减去一个(由于采取了降维优化,这里的\(DP[S_1][S_2]\)记录的是未考虑大因子为当前大因子的数的情况)。

需要注意的是,若考虑完了一个大因子的所有数后开始考虑下一个,或者当前数没有大因子时,需要把\(F_1,F_2\)赋值为\(DP\)。(相当于开始了新的一轮\(DP\),之前的\(F_1,F_2\)应该更新掉)。

最后把每种合法状态的和做一个和即可。

#include<bits/stdc++.h>
#define m_p make_pair
#define ll long long
using namespace std;
const int N=501,MAXN=260;
ll p;
int n;
int prime[8]={2,3,5,7,11,13,17,19};
struct node{
	int val,cnt,two;
}a[N];
ll dp[MAXN][MAXN],f1[MAXN][MAXN],f2[MAXN][MAXN];
bool cmp(node x,node y){
	return x.cnt>y.cnt;
}
void ask(int i){
	int tmp=a[i].val;
	for(int j=0;j<8;j++){
		if(tmp%prime[j]==0){
			while(!(tmp%prime[j])) tmp/=prime[j];
			a[i].two|=(1<<j);
		}
	}	
	a[i].cnt=tmp;
}
int main(){
	scanf("%d%lld",&n,&p);
	for(int i=2;i<=n;i++){
		a[i-1].val=i;
		ask(i-1);
	}	
	sort(a+1,a+n,cmp);
	dp[0][0]=1;
	for(int i=1;i<n;i++){
		if(i==1||a[i].cnt==1||a[i].cnt!=a[i-1].cnt){//更新
			memcpy(f1,dp,sizeof(dp));
			memcpy(f2,dp,sizeof(dp));
		}
		for(int j=255;j>=0;j--){//注意,需要逆推
			for(int k=255;k>=0;k--){
				if(j&k) continue;
				if(!(j&a[i].two))f1[j][k|a[i].two]=(f1[j][k|a[i].two]+f1[j][k])%p;
				if(!(k&a[i].two))f2[j|a[i].two][k]=(f2[j|a[i].two][k]+f2[j][k])%p;
			}
		}
		if(a[i].cnt==1||i==n-1||a[i].cnt!=a[i+1].cnt){//合并
			for(int j=0;j<=255;j++){
				for(int k=0;k<=255;k++){
					if(j&k) continue;
					dp[j][k]=((f1[j][k]+f2[j][k])%p-dp[j][k]+p)%p;
				}
			}
		}
	}
    //统计答案:
	ll ans=0;
	for(int j=0;j<=255;j++){
		for(int k=0;k<=255;k++){
			if(j&k) continue;
			ans=(ans+dp[j][k])%p;
		}
	}
	cout<<ans;
	return 0;
}

标签:cnt,寿司,int,two,NOI2015,因子,MAXN,晚宴,DP
From: https://www.cnblogs.com/123456xwd/p/17929541.html

相关文章

  • P1955 [NOI2015] 程序自动分析
    P1955[NOI2015]程序自动分析基本思路考虑到了不等号的不可传递性,所以决定只开相等的并查集。然后突发奇想,觉得可以在找父亲的过程中判断是不是冲突。然而这样就不能路径压缩,显然超时。并且,根本没看清楚数据范围,实际上这题的数很大,裸开数组会爆炸。这是一开始的代码#inclu......
  • P2146 [NOI2015] 软件包管理器 题解
    [NOI2015]软件包管理器题目背景Linux用户和OSX用户一定对软件包管理器不会陌生。通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖(即下载安装这个软件包的安装所依赖的其它软件包),完成所有的配置。Debi......
  • P5070 [Ynoi2015] 即便看不到未来
    题意给定一个序列,静态区间查询区间的长度为\(1\to10\)的极长值域连续段个数。Sol考虑离线下来跑扫描线。枚举右端点,维护每个左端点的答案。不难想到,\(i\)对\(lst[i]\)是没有贡献的,考虑右端点为\(i-1\),若此时的\(l\lelst[i]\)。\(i\)不作贡献。所以我们把值域上......
  • P2150 [NOI2015] 寿司晚宴
    写了两天。。。就是说,状态压缩DP可以不用显示写出考虑到第i个数,直接每次考虑加入一个数会对当前状态造成的影响即可。这道题发现了大质因数只有1个之后,就需要考虑有相同的大质因数之间的转移,和大质因数不同的之间的转移。然后会发现没有大质因数的数需要特殊处理……然后就好......
  • NOI2015酱油记
    这么一想我好像破掉了两个flag。。。一个是Ag的flag……(Wc、Ctsc、Apio都是Ag另一个是二试被翻的flag……(NOIP,省选,Ctsc,各种二试被####DAY-1报到日从长春坐一晚上火车到北京然后坐高铁到杭州。。。一下车一股热气真爽~下了车看到好多人……黄学长居然和我们一趟线?黄学长:......
  • Ynoi2015 我回来了
    介绍个最劣解\(O(m\sqrtn+n\sqrtn+n\alpha(n)\lnn)\)做法。首先令\(b_i\getsa_i-1\),区间\([l,r]\)的答案就是:\[r-l+1+\sum\limits_{k=l}^r\text{mex}_{i=l}^r\left\lfloor\frac{b_i}{k}\right\rfloor\]考虑如何动态维护后面那个式子。我们对每一个\(k\in[1,n]\)维......
  • [NOI2015] 荷马史诗
    题目链接洛谷LOJ题目分析哈夫曼编码模板题。使用k进制,即编码时将k个点合并为一个。最后要求的就是哈夫曼编码的长度,以及哈夫曼树最深的节点的深度。注意最后合并的时候可能会出现不满一层的情况,所以要在刚开始补成能恰好合并的哈夫曼树。最后剩下一个节点,即需要合并掉......
  • 洛谷 P3243 [HNOI2015] 菜肴制作 - toposort 需自己理解翻译题面
    P3243[HNOI2015]菜肴制作题目描述知名美食家小A被邀请至ATM大酒店,为其品评菜肴。ATM酒店为小A准备了\(n\)道菜肴,酒店按照为菜肴预估的质量从高到低给予\(1\)到\(n\)的顺序编号,预估质量最高的菜肴编号为\(1\)。由于菜肴之间口味搭配的问题,某些菜肴必须在另一些......
  • 【题解】[HNOI2015] 落忆枫音
    题目传送门感觉这题挺有意思的,遂写。题目大意给出一个有向无环图,再给定两个点\(s\)和\(t\),表示在点\(s\)和\(t\)间加上一条边。求这个图有多少种生成树。题目分析首先考虑不加边之前的情况,假设给定下面这个图:根据树的定义,除根节点外的节点有且只有一个父亲节点,也就......
  • 【题解】[六省联考 2017] 寿司餐厅
    题目描述:Kiana最近喜欢到一家非常美味的寿司餐厅用餐。每天晚上,这家餐厅都会按顺序提供\(n\)种寿司,第\(i\)种寿司有一个代号\(a_i\)和美味度\(d_{i,i}\),不同种类的寿司有可能使用相同的代号。每种寿司的份数都是无限的,Kiana也可以无限次取寿司来吃,但每种寿司每次只能......