• CF-300E-Empire Strikes Back(二分答案 素因子分解+筛法 or 奇葩搞法)


    题意:http://codeforces.com/problemset/problem/300/E

    问你最小的n,满足 n!整除 ∏ a【i】!

    思路:

    套路写法是筛出所有素因子,数量统计好

    然后二分判断答案里是否有足够的因子数。

    二分上界注意一下:(n+m)! /(n!*m!) =C(n+m,m)所以∑a【i】一定足够

    还有一种写法是:https://blog.csdn.net/dg_programming/article/details/38903083?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

    其实可以这样理解,对于一个 i 来说,如果 i 是合数,那么 i 的素因子应该全得再加上 p[ i ] 个,而这里处理的是将 i 的最小素因子加p [ i ]个,然后将 i / minP[ i ](表示i的最小素因子)加p[ i ]个,i 可以从大到小进行循环,那么如果 i / minP[ i ]还是合数的话,那么会在 i = i / minP[ i ]时处理接下来的 i 的素因子:

    有点背包的意思

      1 #define IOS ios_base::sync_with_stdio(0); cin.tie(0);
      2 #include <cstdio>//sprintf islower isupper
      3 #include <cstdlib>//malloc  exit strcat itoa system("cls")
      4 #include <iostream>//pair
      5 #include <fstream>//freopen("C:\Users\13606\Desktop\Input.txt","r",stdin);
      6 #include <bitset>
      7 //#include <map>
      8 //#include<unordered_map>
      9 #include <vector>
     10 #include <stack>
     11 #include <set>
     12 #include <string.h>//strstr substr strcat
     13 #include <string>
     14 #include <time.h>// srand(((unsigned)time(NULL))); Seed n=rand()%10 - 0~9;
     15 #include <cmath>
     16 #include <deque>
     17 #include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less
     18 #include <vector>//emplace_back
     19 //#include <math.h>
     20 #include <cassert>
     21 #include <iomanip>
     22 //#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor
     23 #include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare)
     24 using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation
     25 //******************
     26 clock_t __START,__END;
     27 double __TOTALTIME;
     28 void _MS(){__START=clock();}
     29 void _ME(){__END=clock();__TOTALTIME=(double)(__END-__START)/CLOCKS_PER_SEC;cout<<"Time: "<<__TOTALTIME<<" s"<<endl;}
     30 //***********************
     31 #define rint register int
     32 #define fo(a,b,c) for(rint a=b;a<=c;++a)
     33 #define fr(a,b,c) for(rint a=b;a>=c;--a)
     34 #define mem(a,b) memset(a,b,sizeof(a))
     35 #define pr printf
     36 #define sc scanf
     37 #define ls rt<<1
     38 #define rs rt<<1|1
     39 typedef pair<int,int> PII;
     40 typedef vector<int> VI;
     41 typedef unsigned long long ull;
     42 typedef long long ll;
     43 typedef double db;
     44 const db E=2.718281828;
     45 const db PI=acos(-1.0);
     46 const ll INF=(1LL<<60);
     47 const int inf=(1<<30);
     48 const db ESP=1e-9;
     49 const int mod=(int)1e9+7;
     50 const int N=(int)1e7+100;
     51 
     52 int prime[N];
     53 ll phi[N];
     54 bool unprime[N];
     55 
     56 ///O(NloglogN),推荐
     57 void phi_table()
     58 {
     59     int i, j;
     60     for (i = 2; i < N; ++i)
     61         if (!phi[i])
     62             for (j = i; j < N; j += i)
     63             {
     64                 if (!phi[j]) phi[j] = j;
     65                 phi[j] -= phi[j] / i; ///简化后的代码
     66             }
     67 }
     68 
     69 ///O(N)
     70 void linear_phi_table2()
     71 {
     72     int i, j, k = 0;
     73     for (i = 2; i < N; i++)
     74     {
     75         if (!unprime[i]) ///若i为素数,phi(i)=i-1
     76         {
     77             prime[k++] = i;
     78             phi[i] = i - 1;
     79         }
     80         for (j = 0; j < k && prime[j] * i < N; j++)
     81         {
     82             unprime[prime[j] * i] = true;
     83             if (i % prime[j]) ///若i和p互素,则phi(i*p) = phi(i) * phi(p) = phi(i) * (p-1)
     84                 phi[prime[j] * i] = phi[i] * (prime[j] - 1);
     85             else
     86             {
     87                 ///此时有i=kp,则
     88                 ///phi(p*kp) = phi(k*p^2) = p*phi(kp)
     89                 phi[prime[j] * i] = phi[i] * prime[j];
     90                 break;
     91             }
     92         }
     93     }
     94 }
     95 
     96 int a[N],cnt[N];
     97 ll cp[N],check_cp[N];
     98 ll er[100];
     99 ll dp[N];
    100 
    101 bool check(int r,ll ans)
    102 {
    103     for(int i=1;i<=r;++i)
    104         check_cp[i]=0;
    105     for(int i=1;i<=r;++i)
    106     {
    107         ll temp=prime[i];
    108         while(ans/temp)
    109         {
    110             check_cp[i]+=ans/temp;
    111             temp*=prime[i];
    112         }
    113     }
    114     for(int i=1;i<=r;++i)
    115         if(cp[i]>check_cp[i])return 0;
    116     return 1;
    117 }
    118 
    119 ll get(int r)
    120 {
    121     ll ans=er[50];
    122     for(int i=50;i>=1;--i)
    123     {
    124         if(check(r,ans-er[i]))
    125             ans-=er[i];
    126     }
    127     return ans;
    128 }
    129 
    130 int main()
    131 {
    132 /*    int tt=0;
    133     for(int i=1;i<=1000;++i)
    134     {
    135         int t=i;
    136         while(t%2)tt++,t/=2;
    137     }
    138     for(int i=1;i<=1000;++i)
    139     {
    140         int t=i;
    141         while(t%2)tt++,t/=2;
    142     }
    143     pr("%d
    ",tt);
    144  */
    145     er[1]=1;
    146     for(int i=2;i<=100;++i)
    147     {
    148         er[i]=er[i-1]*2;
    149     //    pr("%d: %lld
    ",i,er[i]);
    150     }
    151     linear_phi_table2();
    152 //    for(int i=0;i<=100;++i)pr("%d: %d
    ",i,prime[i]);
    153     int n;
    154     sc("%d",&n);
    155     int top=0;
    156     for(int i=1;i<=n;++i)sc("%d",&a[i]),++cnt[a[i]],top=a[i]>top?a[i]:top;
    157     if(top==1)
    158     {
    159         pr("1
    ");
    160         return 0;
    161     }
    162     int r=0;
    163     for(int i=1e7;i>=1;--i)
    164         cnt[i]+=cnt[i+1];
    165     for(int i=1;i<=1e7;++i)
    166     {
    167         if(prime[i]>top)
    168         {
    169             r=i-1;
    170             break;
    171         }
    172     }r++;
    173 //    for(int i=1;i<=10000000;++i)
    174 //        pr("%d: %d
    ",i,prime[i]);
    175     for(int i=r;i>=1;--i)
    176         prime[i]=prime[i-1];
    177     for(int i=1;i<=r;++i)
    178     {
    179         int now=prime[i];
    180         ll sum=0;
    181         for(int j=1;j*now<=top;++j)
    182         {
    183             if(j==1)dp[j*now]=1;
    184             else
    185             {
    186                 dp[j*now]=0;
    187                 if(j%now==0)dp[j*now]=dp[j]+1;
    188                 else dp[j*now]=dp[now];
    189             }
    190             sum+=dp[j*now]*cnt[j*now];
    191         }
    192         cp[i]=sum;
    193     }
    194     pr("%lld
    ",get(r));
    195     return 0;
    196 }
    197 
    198 /**************************************************************************************/
  • 相关阅读:
    使用javamail发信过程中的一些问题及解决方法
    互联网标准
    发送邮件报错javax.activation.UnsupportedDataTypeException: no object DCH for MIME type text/plain; charset=UTF-8
    在用split分割处理csv数据时,使用不包含在双引号中的逗号进行分割
    java 网络代理官方资料
    ORA-28000错误的原因及解决办法
    日文软件下载站点
    Azure 入门
    ElasticSearch 5学习(10)——结构化查询(包括新特性)
    ElasticSearch 5学习(9)——映射和分析(string类型废弃)
  • 原文地址:https://www.cnblogs.com/--HPY-7m/p/12584609.html
Copyright © 2020-2023  润新知