【HDOJ5943】Kingdom of Obsession(数论)
题意:给定n个人,n个座位,人的编号是【1,n】,座位的编号是【s+1,s+n】,编号为i的人能坐在编号为j的座位上的条件是j%i=0
问是否存在一组方案使得座位和人一一对应
n,s<=1e9
思路:首先考虑如果区间【1,n】和【s+1,s+n】有重叠则重叠部分必然座位和人两两编号相同对应,因为这样能使解的空间更加宽松
现在考虑两端无重叠且等长的区间,显然如果靠后那段区间中出现了大于1个质数则他们都必须要用1,必然无解
根据质数密度分布可以近似算出阈值(据tls说是60?),如果区间长度大于阈值则必然无解,否则跑二分图最大匹配
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef unsigned long long ull; 6 typedef long double ld; 7 typedef pair<int,int> PII; 8 typedef pair<ll,ll> Pll; 9 typedef vector<int> VI; 10 typedef vector<PII> VII; 11 typedef pair<ll,ll>P; 12 #define N 2000000+10 13 #define M 200000+10 14 #define INF 1e9 15 #define fi first 16 #define se second 17 #define MP make_pair 18 #define pb push_back 19 #define pi acos(-1) 20 #define mem(a,b) memset(a,b,sizeof(a)) 21 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++) 22 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--) 23 #define lowbit(x) x&(-x) 24 #define Rand (rand()*(1<<16)+rand()) 25 #define id(x) ((x)<=B?(x):m-n/(x)+1) 26 #define ls p<<1 27 #define rs p<<1|1 28 #define fors(i) for(auto i:e[x]) if(i!=p) 29 30 const int MOD=998244353,inv2=(MOD+1)/2; 31 //int p=1e4+7; 32 //double eps=1e-6; 33 int dx[4]={-1,1,0,0}; 34 int dy[4]={0,0,-1,1}; 35 36 int head[N],vet[N],nxt[N],match[N],flag[N],a[N],b[N],tot; 37 38 int read() 39 { 40 int v=0,f=1; 41 char c=getchar(); 42 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 43 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 44 return v*f; 45 } 46 47 ll readll() 48 { 49 ll v=0,f=1; 50 char c=getchar(); 51 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 52 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 53 return v*f; 54 } 55 56 void add(int a,int b) 57 { 58 nxt[++tot]=head[a]; 59 vet[tot]=b; 60 head[a]=tot; 61 } 62 63 int dfs(int u) 64 { 65 flag[u]=1; 66 int e=head[u]; 67 while(e) 68 { 69 int v=vet[e]; 70 if(!match[v]||!flag[match[v]]&&dfs(match[v])) 71 { 72 match[v]=u; 73 return 1; 74 } 75 e=nxt[e]; 76 } 77 return 0; 78 } 79 80 int main() 81 { 82 //freopen("1.in","r",stdin); 83 //freopen("1.out","w",stdout); 84 int cas=read(); 85 rep(v,1,cas) 86 { 87 int n=read(),s=read(); 88 int x1,y1,x2,y2; 89 if(n<s+1) x1=1,y1=n,x2=s+1,y2=s+n; 90 else x1=1,y1=s,x2=n+1,y2=s+n; 91 if(y1-x1>100) printf("Case #%d: No\n",v); 92 else 93 { 94 int n=0; 95 rep(i,x1,y1) 96 { 97 n++; a[n]=i; 98 } 99 n=0; 100 rep(i,x2,y2) 101 { 102 n++; b[n]=i; 103 } 104 rep(i,1,n) head[i]=match[i]=0; 105 tot=0; 106 rep(i,1,n) 107 rep(j,1,n) 108 if(b[j]%a[i]==0) add(i,j); 109 int ans=0; 110 rep(i,1,n) 111 { 112 rep(j,1,n) flag[j]=0; 113 if(dfs(i)) ans++; 114 } 115 if(ans==n) printf("Case #%d: Yes\n",v); 116 else printf("Case #%d: No\n",v); 117 } 118 } 119 return 0; 120 }
null