「CF986F」 Oppa Funcan Style Remastered

「CF986F」 Oppa Funcan Style Remastered

Link

首先发现分解成若干个 \(k\) 的因数很蠢,事实上每个因数都是由某个质因子的若干倍组成的,所以可以将问题转换为分解成若干个 \(k\) 的质因子之和。

此时质因子个数最多也就 \(12\) 个。

然后就不会了。

注意到题目可以转化为判断 \(\sum_{i=1}^kp_ix_i=n\) 是否有非负整数解。

且若 \(\sum_{i=1}^kp_ix_i=m\) 有解,则 \(\sum_{i=1}^kp_ix_i=m+p_i(1\le i\le k)\)一定 有解。

我们考虑在 \(\bmod p\) 意义下建出一张图。在 \((i,(i+p_i)\bmod p)\) 之间连边,然后跑最短路。

最后我们就只需要判断 \(\mathrm{dis}_{n\bmod p}\)\(n\) 的大小关系即可。

注意本题在质因子个数 \(\le 2\) 时需要特判。

/*---Author:HenryHuang---*/
/*---Never Settle---*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=4e6+5;
ll pri[maxn],cnt;
bool p[maxn*9];
ll P;
void init(){
	for(ll i=2;i<=P;++i){
		if(!p[i]) pri[++cnt]=i;
		for(ll j=1;j<=cnt&&i*pri[j]<=P;++j){
			p[i*pri[j]]=1;
			if(i%pri[j]==0) break; 
		}
	}
}
ll a[50],tot;
ll dis[100005];
vector<pair<int,int> > e[100005];
priority_queue<pair<ll,ll> > Q;
void exgcd(ll a,ll b,ll &x,ll &y){
	if(!b){
		x=1,y=0;
		return ;
	}
	exgcd(b,a%b,y,x);
	y-=a/b*x;
}
ll gcd(ll a,ll b){
	if(!b) return a;
	return gcd(b,a%b);
}
map<ll,ll> mp;
ll owo=0;
vector<pair<ll,ll>> q[100];
ll ans[10010];
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	ll T;cin>>T;P=sqrt(1e15+0.5);init();
	for(ll _=1;_<=T;++_){
		ll n,k;cin>>n>>k;
		if(!mp[k]) mp[k]=++owo;
		q[mp[k]].emplace_back(n,_);
	}
	for(auto xs:mp){
		ll k,u;tie(k,u)=xs;tot=0;
		for(ll i=1;i<=cnt&&1ll*pri[i]*pri[i]<=k;++i){
			if(k%pri[i]==0){
				a[++tot]=pri[i];
				while(k%pri[i]==0) k/=pri[i];
			}
		}
		if(k!=1) a[++tot]=k;
		if(k==1){
			for(auto x:q[u]){
				ll n,id;tie(n,id)=x;
				ans[id]=0;
			}
		}
		else if(tot==1){
			for(auto x:q[u]){
				ll n,id;tie(n,id)=x;
				if(n%a[1]) ans[id]=0;
				else ans[id]=1;
			}
		}
		else if(tot==2){
			ll x,y;
			exgcd(a[1],a[2],x,y);
			x=(x%a[2]+a[2])%a[2];
			for(auto xx:q[u]){
				ll n,id;tie(n,id)=xx;
				ll tx=n%a[2]*x%a[2];
				ll ty=(n-a[1]*tx)/a[2];
				if(ty<0) ans[id]=0;
				else ans[id]=1;
			}
		}
		else{
			memset(dis,0x3f,sizeof dis);
			for(ll i=0;i<a[1];++i) e[i].clear();
			for(ll i=2;i<=tot;++i)
				for(ll j=0;j<a[1];++j)
					e[j].emplace_back((j+a[i])%a[1],a[i]);
			dis[0]=0;Q.emplace(0,0);
			while(!Q.empty()){
				ll u;ll d;
				tie(d,u)=Q.top();Q.pop();
				d=-d;
				if(d!=dis[u]) continue;
				for(auto x:e[u]){
					ll v,w;tie(v,w)=x;
					if(dis[v]>dis[u]+w){
						dis[v]=dis[u]+w;
						Q.emplace(-dis[v],v);
					}
				}
			}
			for(auto x:q[u]){
				ll n,id;tie(n,id)=x;
				if(dis[n%a[1]]<=n) ans[id]=1;
				else ans[id]=0;
			}
		}
	}
	for(ll i=1;i<=T;++i){
		cout<<(ans[i]?"YES":"NO")<<'\n';
	}
	return 0;
}
posted @ 2021-02-23 08:32  Henry__Huang  阅读(163)  评论(0编辑  收藏  举报