[因子背包] CF1647D Madoka and the Best School in Russia

1 篇文章 0 订阅

由这次的D题从杜老师那学会的比较新奇的背包,我暂且将其命名为因子背包
题意:
一个数 x x x被称为好数,当且仅当他被 d d d整除而不被 d 2 d^2 d2整除。
给定一个数 n n n,问是否有超过两种组成方式,让它成为一个或若干个好数的乘积。
T T T组询问, T < = 100 T<=100 T<=100 n , d < = 1 0 9 n,d<=10^9 n,d<=109

Solution 1
首先定然可以很暴力的将所有 n n n的好数因子给找出来,我们需要的就是用这些数来构成 n n n
由于一个数可以用若干次,所以其实本质上这是一个完全背包问题,我们考虑正常的完全背包我们咋做的。
F [ i ] [ j ] = F [ i − 1 ] [ j ] + F [ i − 1 ] [ j / d [ i ] ] F[i][j]=F[i-1][j]+F[i-1][j/d[i]] F[i][j]=F[i1][j]+F[i1][j/d[i]],第一维可以滚掉,也就是 F [ j ] + = F [ j / d [ i ] ] F[j]+=F[j/d[i]] F[j]+=F[j/d[i]]
问题来了,由于值域太大,我们不可能遍历整个值域来做这个背包,但这时我们发现由于最后能对 F [ n ] F[n] F[n]做出贡献的只有 n n n的因子,而对 n n n的因子做出贡献的则是 n n n的因子的因子(也是 n n n的因子),因此我们只需要从小到大遍历 n n n的所有因子(最多也就 1300 1300 1300个左右),这样最终贡献给 F [ n ] F[n] F[n]的答案一定是正确的。

现在只剩下一个问题了,虽然我们只需要遍历 n n n的所有因子,但是这些因子可能也很大,并不能直接开一个这么大的数组。
我会map!
额,多了个 l o g log log,这题好像有可能会T。
那咋办?
可以用一个“双指针”的方法,我们开两个数组 i d [ 1 e 5 + 5 ] , g i d [ 1 e 5 + 5 ] id[1e5+5],gid[1e5+5] id[1e5+5],gid[1e5+5]
对于每一个因子 c [ i ] c[i] c[i],如果他小于等于 1 e 5 1e5 1e5,那么我们就将 i d [ c [ i ] ] = i id[c[i]]=i id[c[i]]=i,否则 g i d [ n / c [ i ] ] = i gid[n/c[i]]=i gid[n/c[i]]=i,这样就可以把值域全部映射回因子个数里,用的时候也判断一下要用的数是通过 i d id id还是 g i d gid gid存放的即可。

Code:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#define ll long long
#define lowbit(x) x&(-x)
#define mp make_pair
#define rep(i,n) for(int i=1;i<=n;i++)
using namespace std;
const int mod=998244353;
const int maxn=1e7+5;
const int maxm=1e5;
inline int read()
{
	int 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*10+(c-'0');
		c=getchar();
	}
	return x*f;
}
int T;
int f[2050];
int id[100050],gid[100050];
int tot,c[2050];
signed main()
{
	T=read();
	while(T--)
	{
		tot=0;
		int n=read(),d=read();
		for(int i=1;i*i<=n;i++)
		{
			if(n%i==0) 
			{
				if(n/i==i) c[++tot]=i;
				else c[++tot]=i,c[++tot]=n/i;
			}	
		}
		sort(c+1,c+tot+1);
		for(int i=1;i<=tot;i++)
		{
			if(c[i]<=maxm) id[c[i]]=i;
			else gid[n/c[i]]=i;
		}
		f[1]=1;
		for(int i=1;i<=tot;i++)
		{
			if((c[i]%d==0)&&((c[i]/d)%d!=0))
			{
				for(int j=1;j<=tot;j++)
				{
					if((n/c[i])%c[j]==0)
					{
						int x=c[i]*c[j];
						int y=(x<=maxm)?id[x]:gid[n/x];
						f[y]=min(f[y]+f[j],2);
					}
				}
			}
		}
		if(f[tot]>=2) cout<<"Yes"<<endl;
		else cout<<"No"<<endl;	
		for(int i=1;i<=tot;i++) f[i]=0;
	}
 } 
以下是截至2021年10月的全球动漫评分排行榜前100名: 1.《Fullmetal Alchemist: Brotherhood》 2.《Steins;Gate》 3.《Your Lie in April》 4.《Hunter x Hunter (2011)》 5.《Gintama》 6.《Haikyuu!!》 7.《Attack on Titan》 8.《Code Geass: Lelouch of the Rebellion》 9.《Clannad: After Story》 10.《Death Note》 11.《One Punch Man》 12.《Jojo's Bizarre Adventure》 13.《Cowboy Bebop》 14.《Baccano!》 15.《Neon Genesis Evangelion》 16.《Spirited Away》 17.《Monogatari Series》 18.《Shigatsu wa Kimi no Uso》 19.《Toradora!》 20.《Tengen Toppa Gurren Lagann》 21.《K-On!》 22.《The Melancholy of Haruhi Suzumiya》 23.《Fate/Zero》 24.《One Piece》 25.《Rurouni Kenshin: Trust and Betrayal》 26.《Dragon Ball Z》 27.《Legend of the Galactic Heroes》 28.《Hajime no Ippo》 29.《Ghost in the Shell: Stand Alone Complex》 30.《Nana》 31.《Samurai Champloo》 32.《Great Teacher Onizuka》 33.《Anohana: The Flower We Saw That Day》 34.《Kimi no Na wa.》 35.《Kara no Kyoukai》 36.《Psycho-Pass》 37.《Bakemonogatari》 38.《No Game No Life》 39.《Nichijou》 40.《Usagi Drop》 41.《Kill la Kill》 42.《Akira》 43.《Durarara!!》 44.《Tatami Galaxy》 45.《Katanagatari》 46.《Berserk》 47.《Princess Mononoke》 48.《Higurashi no Naku Koro ni》 49.《Soul Eater》 50.《Black Lagoon》 51.《Naruto》 52.《Fairy Tail》 53.《Kimi ni Todoke》 54.《Serial Experiments Lain》 55.《Kuroko no Basket》 56.《Chihayafuru》 57.《Hyouka》 58.《Bleach》 59.《Sakamichi no Apollon》 60.《Golden Time》 61.《Love Live! School Idol Project》 62.《Cardcaptor Sakura》 63.《Gekkan Shoujo Nozaki-kun》 64.《Full Metal Panic!》 65.《Mobile Suit Gundam: Iron-Blooded Orphans》 66.《K-On! Movie》 67.《Kizumonogatari》 68.《Re:Zero kara Hajimeru Isekai Seikatsu》 69.《Shirobako》 70.《Yahari Ore no Seishun Love Comedy wa Machigatteiru.》 71.《Darker than Black》 72.《Honey and Clover》 73.《Zankyou no Terror》 74.《Usagi Drop Specials》 75.《Mahou Shoujo Madoka★Magica》 76.《Bungou Stray Dogs》 77.《Kara no Kyoukai 5: Mujun Rasen》 78.《K-On! 2》 79.《Toaru Kagaku no Railgun》 80.《Kimi ga Nozomu Eien》 81.《Grisaia no Kajitsu》 82.《Gochuumon wa Usagi Desu ka?》 83.《Shinsekai yori》 84.《Nodame Cantabile》 85.《Bungou Stray Dogs 2nd Season》 86.《Made in Abyss》 87.《Gin no Saji》 88.《Ranma ½》 89.《K-On!!》 90.《Sword Art Online》 91.《Hibike! Euphonium》 92.《Nisekoi》 93.《K-On!: Live House!》 94.《K-On!: Keikaku!》 95.《D-Frag!》 96.《K-On!: Ura-ON!》 97.《K-On!: College》 98.《K-On!: Fude Pen - Boru Pen》 99.《K-On!: Plan!》 100.《K-On!: Movie - Wonderful♪》
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值