Kingdom of Obsession
题目链接: Kingdom of Obsession HDU - 2853
题意
给你一个起点s,和n要求从s+1到s+n的自然数按照一定次序排序,满足自己的值一定能整除自己的排序号
思路
题3目中的s和n都很大,所以暴力运算并不可取,那么我们就需要自己优化。题目显然一个素数在1以外找不到自己的座位,那么就可以从素数入手,数学原理可得。在1到1e9范围内任何两个素数之差,一定不会超过500,所以这个n一定不会超过五百,超过直接输出NO即可,在500的数据量下我们就可以用二分图匹配了,注意这里有一个陷阱,在一种情况下n可以为非常大的数,也会符合条件,就是1到n与s到s+n的区间有大量数字重叠的情况下,我们只需特判,就将重叠的地方删去,用一个 if (n > s) swap(n,s);
即可
代码
#include <bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(ll i = (ll)j;i <= (ll)k;i ++)
#define per(i,j,k) for(ll i = (ll)j;i >= (ll)k;i --)
#define debug(x) cerr<<#x<<" = "<<(x)<<endl
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
typedef double db;
typedef long long ll;
const ll MAXN = (ll)1e3+7;
const ll INF = (ll)0x3f3f3f3f;
ll K,N,M;
vector<ll> E[MAXN];
ll used[MAXN],nxt[MAXN];//在男生的某次访问里,女生能不能匹配到 //如果匹配到的话,这个男生是谁
bool Find(ll x){
rep(i,0,E[x].size()-1){
ll v = E[x][i];
if (!used[v]){
used[v] = 1;
if (!nxt[v] || Find(nxt[v])){ //如果这个女生没有匹配到人,或者她匹配的男生可以腾位置的
nxt[v] = x;
return true;
}
}
}
return false;
}
ll match(){
ll sum = 0;
rep(i,1,N){
mmm(used,0);
if (Find(i)) sum ++;
}
return sum;
}
void init(){
rep(i,1,N) E[i].clear();
mmm(nxt,0);
}
int main()
{
ll T;
scanf("%lld",&T);
rep(ca,1,T) {
ll flag = 0;
ll n,s;
scanf("%lld %lld",&n,&s);
if (n > s) swap(n,s);
if (n >= 1000) flag = 1;
else {
N = n;
init();
rep(i,1,n) {
rep(j,1,n) {
if ((i+s)%j == 0) E[i].pb(j);
}
}
if (match() != n) flag = 1;
}
printf("Case #%lld: ",ca);
if (flag) puts("No");
else puts("Yes");
}
}