• 2020牛客暑期多校训练第四场部分


    B、Basic Gcd Problem

    此题wa了16次,恶心的我不行
    可以发现当前f[x] 肯定是c的幂次,那么就看x最大时c的多少幂次了。再看x和i的gcd,也就相当于x的约数
    在这里插入图片描述
    从上面看出规律,x如果要是最大,会从它的约数里面挑出最大的y,那么这个y也想最大,所以他也会从它的约数里面挑出z

    [x = k * y = k * (p * z) ]

    所以也就是最长的上升的,任意两个数都是倍数关系的序列例如1,2,4,8,32,但是发现,这个不需要可以的去求最长了,最长的个数时固定的,贪心来讲,当前x到下面一个y,y = k * x,那么这个k应该最小,最小应该是什么呢,质数,一个质因子,那么在这个上升子序列里面所有k[i] , 满足y[i] = k[i] * x[i] , 并且肯定每个k都是质因子,长度也就等于n的质因子个数(可以枚举几个数试试)

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <unordered_map>
    #include <vector>
    #include <map>
    #include <list>
    #include <queue>
    #include <cstring>
    #include <cstdlib>
    #include <ctime>
    #include <cmath>
    #include <stack>
    #include <set>
    #pragma GCC optimize(3 , "Ofast" , "inline")
    using namespace std ;
    #define ios ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
    #define x first
    #define y second
    typedef long long ll ;
    const double esp = 1e-6 , pi = acos(-1) ;
    typedef pair<int , int> PII ;
    const int N = 1e6 + 10 , INF = 0x3f3f3f3f , mod = 1e9 + 7;
    ll in()
    {
      ll x = 0 , f = 1 ;
      char ch = getchar() ;
      while(!isdigit(ch)) {if(ch == '-') f = -1 ; ch = getchar() ;}
      while(isdigit(ch)) x = x * 10 + ch - 48 , ch = getchar() ;
      return x * f ;
    }
    ll qmi(ll a , ll b){
      ll res = 1 ;
      while(b) {
        if(b & 1) res = res * a % mod ;
        a = a * a % mod ;
        b >>= 1 ;
      }
      return res ;
    }
    void work(){
      int n , c ;
        scanf("%d%d" , &n , &c) ;
      int ans = 0 ;
      for(int i = 2; i <= n / i ;i ++)
       while(n % i == 0) n /= i , ans ++ ;
      if(n > 1) ans ++ ;
      printf("%d
    " , qmi(c , ans) % mod) ;
      return ;
    }
    int main()
    {
      int t = in() ;
      while(t --) work() ;
      return 0 ;
    }
    /*
    */
    
    

    F、Finding the Order

    在这里插入图片描述
    高手:两个三角形符合两边之和大于第三边,那么两个组合起来就是两个内边加起来大于两个外边

    #include<bits/stdc++.h>
    using namespace std;
    int t,ac,ad,bc,bd;
    int main(){
        cin>>t;
        while(t--){
            cin>>ac>>ad>>bc>>bd;
            if(ac+bd<ad+bc)cout<<"AB//CD"<<endl;else cout<<"AB//DC"<<endl;
        }
        return 0;
    }
    

    H、Harder Gcd Problem

    在这里插入图片描述
    比赛的时候就看出来规律了,只是没敢写,从图里面发现每个质数的所有倍数都可以两两组成一对,尽管这个倍数也可能既是2的倍数也可能是5的倍数,那么每个就枚举一个质数,枚举它的倍数 , 两两组成。但是交上去wa掉了,仔细一想,这个做法是贪心的, 那么这个做法到底够不够贪心呢,既然贪了,就要一贪到底。比较两个质数a , b , 如果a < b,那么在n里面肯定是a的倍数比较多,b的倍数比较小,甚至一个没有,既然贪心了,就要把每个数尽量的都要用了,此时对于a来说,它的倍数比较多,也比较好配对,b就相反,所以先配对b,尽量把b的倍数都用了,所以以此类推,枚举质数的时候从大到小枚举

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <unordered_map>
    #include <vector>
    #include <map>
    #include <list>
    #include <queue>
    #include <cstring>
    #include <cstdlib>
    #include <ctime>
    #include <cmath>
    #include <stack>
    #include <set>
    #pragma GCC optimize(3 , "Ofast" , "inline")
    using namespace std ;
    #define ios ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
    #define x first
    #define y second
    typedef long long ll ;
    const double esp = 1e-6 , pi = acos(-1) ;
    typedef pair<int , int> PII ;
    const int N = 2e5 + 10 , INF = 0x3f3f3f3f , mod = 1e9 + 7;
    ll in()
    {
      ll x = 0 , f = 1 ;
      char ch = getchar() ;
      while(!isdigit(ch)) {if(ch == '-') f = -1 ; ch = getchar() ;}
      while(isdigit(ch)) x = x * 10 + ch - 48 , ch = getchar() ;
      return x * f ;
    }
    int prime[N] , vis[N] , tot ;
    void get()
    {
      for(int i = 2; i < N ; i ++) {
        if(!vis[i]) prime[++ tot] = i ;
        for(int j = 1; j <= tot && i * prime[j] < N ;j ++ ) {
          vis[i * prime[j]] = 1;
          if(i % prime[j] == 0) break ;
        }
      }
    }
    int f[N] ;
    void work(){
      int n = in() ;
      int ans = 0 ;
      for(int i = 1; i <= n ;i ++ ) f[i] = 0 ;
      int pos = lower_bound(prime + 1,  prime + tot + 1 , n) - prime ;
      if(prime[pos] > n) pos -- ;
      for(int i = pos; i >= 1; i -- ) {
        int res = prime[i] ;
        for(int j = n / prime[i] * prime[i] ;j > prime[i] ;j -= prime[i]) {
          if(f[j]) continue ;
          if(!res) res = j ;
          else {
            ans ++ ;
            f[j] = res ;
            f[res] = j ;
            res = 0 ;
          }
        }
      }
      printf("%d
    " , ans) ;
      for(int i = 0 ;i <= n ;i ++ )
       if(f[i] > i)
        printf("%d %d
    " , i , f[i]) ;
      return ;
    }
    int main()
    {
      get() ;
      int t = in() ;
      while(t --) work() ;
      return 0 ;
    }
    /*
    */
    
    

    待续

  • 相关阅读:
    新的工作开始
    昨日的世界
    【Drools-开源业务规则引擎】入门实例(含源码)
    【cs229-Lecture7】支持向量机(SVM)
    【2014年12月6日】HR交流会
    【cs229-Lecture5】生成学习算法:1)高斯判别分析(GDA);2)朴素贝叶斯(NB)
    【图算法】Dijkstra算法及变形
    【图算法】综述
    【云迁移论文笔记】A Comparison of On-premise to Cloud Migration Approaches
    【云迁移论文笔记】Cloud Migration Research:A Systematic Review
  • 原文地址:https://www.cnblogs.com/spnooyseed/p/13347372.html
Copyright © 2020-2023  润新知