zoukankan      html  css  js  c++  java
  • 小 L 与 GCD 题解(数学 hard)

    题目链接

    题目思路

    直接看官方的题解吧链接

    利用容斥的思想

    还有一个就是最后为什么可以直接暴力dfs的结论很妙

    还有(p[a[i]]*=(i+1))的原因

    感觉像很多巧妙的trick结合变成一个hard的题目

    分开每一个小问题可能都会但是结合就gg

    代码

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define debug cout<<"I AM HERE"<<endl;
    using namespace std;
    typedef long long ll;
    const int maxn=1e7+5,inf=0x3f3f3f3f,mod=1e9+7;
    const double eps=1e-6;
    int n,m,k,gd;
    unsigned a[maxn],ans,b[maxn];
    unsigned p[maxn],c[maxn],f[maxn],g[maxn],fp[maxn];
    void dfs(int pos,unsigned g,unsigned temp){
        if(k==0){
            printf("%u",ans);
            exit(0);
        }
        if(g==gd){
            ans=ans+temp;
            k--;
        }
        if(pos>m){
            return ;
        }
        for(int i=pos;i<=m;i++){
            dfs(i+1,__gcd(g,a[b[i]]),temp*b[i]);
        }
    }
    signed main(){
        scanf("%d%d",&n,&k);
        if(n<=30&&(1<<n)<k){
            printf("-1
    ");
            return 0;
        }
        for(int i=1;i<=1e7;i++){
            p[i]=1;
        }
        for(int i=1;i<=n;i++){
            scanf("%u",&a[i]);
            c[a[i]]++;
            p[a[i]]*=(i+1);
        }
        for(int i=1e7;i>=1;i--){
            for(int j=i;j<=1e7;j+=i){
                f[i]+=c[j];
            }
            if(f[i]==0) continue;
            if(f[i]>30){
                gd=i;
                break;
            }
            g[i]=(1<<f[i]);
            for(int j=i+i;j<=1e7;j+=i){
                g[i]-=g[j];
            }
            g[i]--;
            // 还要减去1 空集的情况
            if(g[i]<k){
                k-=g[i];
            }else{
                gd=i;
                break;
            }
        }
        for(int i=1e7;i>gd;i--){
            if(f[i]==0) continue;
            fp[i]=1;
            for(int j=i;j<=1e7;j+=i){
                fp[i]*=p[j];
            }
            for(int j=i+i;j<=1e7;j+=i){
                fp[i]-=fp[j];
            }
            fp[i]--;
            ans+=fp[i];
        }
        for(int i=1;i<=n;i++){
            if(a[i]%gd==0){
                b[++m]=i;
            }
        }
        dfs(1,0,1);
        return 0;
    }
    
    
    
    不摆烂了,写题
  • 相关阅读:
    向IPython Notebook中导入.py文件
    python--时间日期
    python--条件和循环
    python--输入输出
    python--字符串
    python--内置函数
    python--异常
    python--模块
    python--数据结构
    pybrain
  • 原文地址:https://www.cnblogs.com/hunxuewangzi/p/15307470.html
Copyright © 2011-2022 走看看