• 《2020牛客NOIP赛前集训营-提高组(第二场)》


    提高组都是神仙打架%%%

    T1:

    对于每个素数i,显然f[i] = i.

    那么根据唯一分解定理,对于每个合数i,如果它分解后,有多个素因子,那么显然为1.

    否组就是最小的素因子。

    那么,我们可以在线性筛中处理即可。

    线性筛,其实就是利用素数和一个和当前素数肯定有不同素因子的数乘积来筛合数的过程。

    那么,在判断中,当这个数首先要满足只有一个素因子,那么在满足i % prime[j]时,显然筛出的合数只有一个素因子prime[j].

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<double,int> pii;
    const int N = 1e7+5;
    const int M = 1e6+5;
    const LL Mod = 1e9+7;
    //#define rg register
    #define pi acos(-1)
    #define INF 1e18
    #define CT0 cin.tie(0),cout.tie(0)
    #define IO ios::sync_with_stdio(false)
    #define dbg(ax) cout << "now this num is " << ax << endl;
    namespace FASTIO{
        inline int read()
        {
            int x = 0,f = 1;char c = getchar();
            while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();}
            while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}
            return x * f;
        }
        void print(int x){
            if(x < 0){x = -x;putchar('-');}
            if(x > 9) print(x/10);
            putchar(x%10+'0');
        }
    }
    using namespace FASTIO;
    
    bool vis[N];
    int prime[N],tot = 0,f[N];
    void init()
    {
        for(int i = 2;i < N;++i)
        {
            if(!vis[i])
            {
                prime[++tot] = i;
                f[i] = i;
            }
            for(int j = 1;j <= tot && prime[j] * i < N;++j)
            {
                vis[i * prime[j]] = 1;
                f[i * prime[j]] = 1;
                if(i % prime[j] == 0 && f[i] != 1) f[i * prime[j]] = prime[j];
                if(i % prime[j] == 0) break;
            }
        }
    }
    int main()
    {
        init();
        int a,b;a = read(),b = read();
        LL ans = 0;
        for(int i = a;i <= b;++i) ans += f[i];
        printf("%lld
    ",ans);
        system("pause");
        return 0;
    }
    View Code

    T2:

     做法好像蛮多的。

    dp[i]表示是否能得到。

    显然输入的值可以&自己得到。

    且可以发现,对于可以得到的每个数x,去除它的二进制上任意个为1的数,变成的那个数都可以&x来得到那个数。

    所以我们可以枚举每个数然后枚举去除几个0然后再去更新dp。

    但是其实并没有必要枚举几个0.

    我们倒着按值域dp,每次都去除每个位上的一个0,可以发现,因为是倒着枚举值域,所以最后所有数都会被包括在里面。(和枚举几个0等效

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<double,int> pii;
    const int N = 1e6+5;
    const int M = 1e6+5;
    const LL Mod = 1e9+7;
    //#define rg register
    #define pi acos(-1)
    #define INF 1e18
    #define CT0 cin.tie(0),cout.tie(0)
    #define IO ios::sync_with_stdio(false)
    #define dbg(ax) cout << "now this num is " << ax << endl;
    namespace FASTIO{
        inline int read()
        {
            int x = 0,f = 1;char c = getchar();
            while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();}
            while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}
            return x * f;
        }
        void print(int x){
            if(x < 0){x = -x;putchar('-');}
            if(x > 9) print(x/10);
            putchar(x%10+'0');
        }
    }
    using namespace FASTIO;
    
    int dp[N],a[N];
    int main()
    {
        int n,m;n = read(),m = read();
        for(int i = 1;i <= n;++i) a[i] = read(),dp[a[i]] = 1;
        for(int i = N - 1;i >= 0;--i)
        {
            for(int j = 0;(1 << j) <= i;++j)
            {
                if(dp[i] && (i >> j) & 1) dp[i - (1 << j)] = 1;
            }
        }
        while(m--)
        {
            int x;x = read();
            printf("%s
    ",dp[x] == 1 ? "yes" : "no");
        }
        system("pause");
        return 0;
    }
    View Code
  • 相关阅读:
    CentOS 6.3 安装过程
    thinkphp的学习笔记
    全栈工程师之路
    Anne pro 2 开箱实录
    IDEA创建SpringBoot项目整合JPA,连接Oracle数据库,使用Swagger进行测试
    AOP思想的一点想法
    STS(Eclipse)修改Project Exploer背景颜色及字体大小
    IDEA运行Tomcat,控制台日志乱码
    MyBatis自动生成实体类、DAO和XML映射文件,并去掉实体类中的getter和setter方法
    vue+jspdf+html2canvas导出PDF文件
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/13866401.html
Copyright © 2020-2023  润新知