zoukankan      html  css  js  c++  java
  • 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('
    ');
            //printf("%lld
    ", a[cx[up] - 1]);
        }
        return 0;
    }


  • 相关阅读:
    唱歌循序渐进
    523法则
    南北朝鲜
    全名K歌
    《如何进行接口mock测试》
    vue动态添加路由,跳转页面时,页面报错路由重复:vue-router.esm.js?8c4f:16 [vue-router] Duplicate named routes definition: { name: "Login", path: "/login" }
    npm install -g 和npm install --save-dev的关系
    vue项目安装依赖项的时候总是报错
    聊聊 OAuth 2.0 的 Token 续期处理
    Spring Security OAuth 格式化 token 输出
  • 原文地址:https://www.cnblogs.com/riskyer/p/3353209.html
Copyright © 2011-2022 走看看