D. Madoka and the Best School in Russia(因子背包, 完全背包, 大数值不带log的离散化)

//https://codeforces.com/problemset/problem/1647/D
#include<bits/stdc++.h>
#include<unordered_map>
#include<array>
#define ll long long
#define ull unsigned long long
#define all(a) a.begin(),a.end()
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;

const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-8;
const ll mod = 998244353;
const int N = 1e5 + 5;

/*
定义一个数是d的倍数,不是d*d的倍数, 则为完美数
问x是否可以表示为一些完美数的乘积,且方案数大于等于二
*/

ll x, d, id[N], gid[N];
ll f[N];
vector<ll> fac, bea;

void solve()
{
	cin >> x >> d;
	
	fac.clear();
	bea.clear();
	for (ll i = 1; i * i <= x; i++)
	{
		if (x % i == 0)
		{
			fac.push_back(i);
			if (x / i != i)
				fac.push_back(x / i);
		}
	}
	sort(all(fac));
	for (int it : fac)//完美数
		if (it % d == 0 && it / d % d)
			bea.push_back(it);

	for (int i = 0; i < fac.size(); i++)//离散化, 分成一大一小两个数组, 因为正常离散化或者map复杂度高
	{
		if (fac[i] < N)
			id[fac[i]] = i;
		else
			gid[x / fac[i]] = i;
	}

	for (int i = 0; i < fac.size(); i++)
		f[i] = 0;
	f[0] = 1;
	for (int i : bea)
	{
		for (int j : fac)//完全背包
		{
			if (x / i % j == 0)//i * j 是x的因子
			{
				int temp = i * j;
				int idx1 = (temp < N ? id[temp] : gid[x / temp]);//离散
				int idx2 = (j < N ? id[j] : gid[x / j]);
				f[idx1] = f[idx1] + f[idx2];
			}
		}
	}
	int idx = (x < N ? id[x] : gid[1]);
	cout << (f[idx] >= 2 ? "YES" : "NO") << '\n';
}

signed main()
{
	IOS;
	int t = 1;
	cin >> t;
	while (t--)
		solve();
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值