• Codeforces Round #456 (Div. 2) 912E E. Prime Gift


      OvO http://codeforces.com/contest/912/problem/E

      首先把这16个数字拆成2个子集,各自生成所有大小1e18及以下的积

      对于最坏情况,即如下数据

    16
    2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53
    

      把她肢解成

      2 3 5 7 11 13 和  17 19 23 29 31 37 41 43 47 53 两个集合

      这两个集合生成的1e18及以下的积的数量分别为 958460个505756个,并不大,而且两个集合中的积必定是两两不相等的(除了1)。

      记两个集合大小的和为 |S| 

      两个集合生成的积各自排一下序

      然后二分答案,对于每个答案 u,可以 O(|S|) 得到他是第几大。

      具体做法是枚举从到小枚举第一个集合的积 t1,然后计算一下第二个集合的积中有多少积和 t1 相乘小于等于 u

      由于是从大到小枚举的,所以 t1 必然递增,所以第二个集合的积中符合条件的积的数量也必然是递增的,所以只要扫一遍就行。

      然后要注意的是直接用 long long 来进行计算比较好,double的精度貌似不太够

      (参考自这里->http://codeforces.com/contest/912/submission/33938779

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    #include <queue>
    #include <vector>
    
    using namespace std;
    
    typedef long long ll;
    
    const ll INF=1e18;
    const int N=24;
    
    vector<ll> seg[2];
    int p[N],n;
    ll ansid;
    
    void dfs(int li,int ri,ll val,int id)
    {
    	seg[id].push_back(val);
    	for(int i=li;i<=ri;i++)
    		if(INF/p[i]>=val)
    			dfs(i,ri,val*p[i],id);
    }
    
    ll cnt(ll num)
    {
    	int j=0;
    	ll ret=0;
    	for(int i=seg[0].size()-1;i>=0;i--)
    	{
    		while(j<seg[1].size() && seg[1][j]<=num/seg[0][i])
    			j++;
    		ret+=j;
    	}
    	return ret;
    }
    
    void solve()
    {
    	int i,j;
    	dfs(1,min(6,n),1,0);
    	dfs(min(6,n)+1,n,1,1);
    	sort(seg[0].begin(),seg[0].end());
    	sort(seg[1].begin(),seg[1].end());
    //	cout<<seg[0].size()<<' '<<seg[1].size()<<endl;
    	ll li=0,ri=INF,mid;
    	while(li<ri-1)
    	{
    		mid=(li+ri)>>1;
    		if(cnt(mid)>=ansid)
    			ri=mid;
    		else li=mid;
    	}
    	printf("%I64d
    ",ri);
    }
    
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    		scanf("%d",&p[i]);
    	scanf("%I64d",&ansid);
    	solve();
    	return 0;
    }
    
    /*
    
    16
    2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53
    2
    
    */
    

      

  • 相关阅读:
    【BZOJ1089】[SCOI2003]严格n元树(高精度,动态规划)
    【BZOJ1083】[SCOI2005]繁忙的都市(最小生成树)
    【BZOJ1082】[SCOI2005]栅栏(搜索)
    【BZOJ1081】[SCOI2005]超级格雷码(搜索)
    【BZOJ1078】[SCOI2008]斜堆(性质题)
    【BZOJ1077】天平(差分约束)
    【BZOJ1071】[SCOI2007]组队(神仙题)
    【BZOJ1862】[ZJOI2006]游戏排名系统 (Splay)
    【BZOJ1056】[HAOI2008]排名系统(Splay)
    【BZOJ1055】[HAOI2008]玩具取名(动态规划)
  • 原文地址:https://www.cnblogs.com/FxxL/p/8213922.html
Copyright © 2020-2023  润新知