日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

UVALive 6198 A Terribly Grimm Problem

發(fā)布時間:2023/12/16 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 UVALive 6198 A Terribly Grimm Problem 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目大意是


給出L,H ? ? ?10^10范圍

為[L, H]這個連續(xù)的整數(shù)區(qū)間尋找一個序列。

序列的長度要跟[L, H]一樣

然后序列中的數(shù)都是素數(shù),并且互不相同

并且序列中第i個數(shù) 要求是L + i -1的一個素因子?

最后要求序列的字典序最小


然后可以看到L,H很大

但是我們需要注意的是,這個序列長度肯定不會很大

太大了肯定滿足不了題目的要求。


所以這個整數(shù)區(qū)間的數(shù)我們可以一個一個的,先把每個數(shù)都素因子分解了,放起來。

然后就發(fā)現(xiàn)。 這不就是二分圖匹配么。

但是題目求的是字典序最小。

所以我們就對每個數(shù)。

對其所有的素因子,嘗試改變匹配,然后尋找增廣路。

如果能找到。就固定這條邊


#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; }

總結(jié)

以上是生活随笔為你收集整理的UVALive 6198 A Terribly Grimm Problem的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。