题目大意是
给出L,H 10^10范围
为[L, H]这个连续的整数区间寻找一个序列。
序列的长度要跟[L, H]一样
然后序列中的数都是素数,并且互不相同
并且序列中第i个数 要求是L + i -1的一个素因子
最后要求序列的字典序最小
然后可以看到L,H很大
但是我们需要注意的是,这个序列长度肯定不会很大
太大了肯定满足不了题目的要求。
所以这个整数区间的数我们可以一个一个的,先把每个数都素因子分解了,放起来。
然后就发现。 这不就是二分图匹配么。
但是题目求的是字典序最小。
所以我们就对每个数。
对其所有的素因子,尝试改变匹配,然后寻找增广路。
如果能找到。就固定这条边
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#define MAXN 111111
#define N 505
using namespace std;
bool tag[MAXN];
int p[MAXN];
int cnt;
int mark[5555], used[5555];
int cx[N], cy[5555];
vector<int>g[N];
int ans[N];
int m, up;
long long l, r;
long long a[MAXN];
set<long long>s;
map<long long, int> id;
void getprime()
{cnt = 0;tag[1] = 1;for(int i = 2; i < 100000; i++){if(!tag[i]) p[cnt++] = i;for(int j = 0; j < cnt && p[j] * i < 100000; j++){tag[i * p[j]] = 1;if(i % p[j] == 0) break;}}
}
void get(long long x)
{for(int i = 0; i < cnt && x >= (long long)p[i] * (long long)p[i]; i++)if(x % p[i] == 0){s.insert(p[i]);while(x % p[i] == 0) x /= p[i];}if(x != 1)s.insert(x);
}
void get2(long long x)
{long long tx = x;for(int i = 0; i < cnt && x >= (long long)p[i] * (long long)p[i]; i++)if(x % p[i] == 0){long long tmp = (long long)p[i];while(x % tmp == 0) x /= tmp;g[tx - l + 1].push_back(id[tmp]);}if(x != 1)g[tx - l + 1].push_back(id[x]);
}
int path(int u)
{int sz = g[u].size();for(int i = 0; i < sz; i++){int v = g[u][i];if(!mark[v] && !used[v]){mark[v] = 1;if(cy[v] == -1 || path(cy[v])){cx[u] = v;cy[v] = u;return 1;}}}return 0;
}bool ok(int t)
{memset(cy, -1, sizeof(cy));for(int i = t + 1; i <= up; i++){memset(mark, 0, sizeof(mark));if(!path(i)) return false;}return true;
}
void fix()
{for(int i = 1; i <= up; i++){int sz = g[i].size();for(int j = 0; j < sz; j++){int v = g[i][j];if(used[v]) continue;cx[i] = v;used[v] = 1;if(!ok(i)) used[v] = 0;else break;}used[cx[i]] = 1;}
}
void out(long long a )
{if(a >= 10) out(a / 10);putchar('0' + a % 10);
}
int main()
{getprime();while(scanf("%lld%lld", &l, &r) != EOF){if(l == 0 && r == 0) break;s.clear();id.clear();up = r - l + 1;for(int i = 1; i <= up; i++) g[i].clear();memset(ans, -1, sizeof(ans));memset(used, 0, sizeof(used));m = 0;for(long long i = l; i <= r; i++)get(i);for(set<long long>::iterator it = s.begin(); it != s.end(); it++){a[m++] = *it;id[a[m - 1]] = m;}for(long long i = l; i <= r; i++)get2(i);fix();for(int i = 1; i < up; i++){//printf("%lld ", a[cx[i] - 1]);out(a[cx[i] - 1]);putchar(' ');}out(a[cx[up] - 1]);putchar('\n');//printf("%lld\n", a[cx[up] - 1]);}return 0;
}