生活随笔
收集整理的這篇文章主要介紹了
UVALive 6198 A Terribly Grimm Problem
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目大意是
給出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;
}
總結
以上是生活随笔為你收集整理的UVALive 6198 A Terribly Grimm Problem的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。