牛客2018多校第六场 J Heritage of skywalkert - nth_element

传送门

题意:提供一个随机生成函数,让你生成n个数,然后问你其中能找到的两个数的最小公倍数 最大 是多少。

思路:可以用nth_element()函数在O(n)下求出前 15 个大的数(当然,100个数也是可以的),暴力枚举这15个数两两求最小公倍数的结果。当然可以用小根堆优先队列,保证队列中有15个最大的数。

  (雾,由于是随机数,互质的概率大。

// #include<bits/stdc++.h>
//#include<unordered_map>
#include<unordered_set>
#include<functional>
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<climits>
#include<cstring>
#include<cstdlib>
#include<cstddef>
#include<cstdio>
#include<memory>
#include<vector>
#include<cctype>
#include<string>
#include<cmath>
#include<queue>
#include<deque>
#include<ctime>
#include<stack>
#include<map>
#include<set>
 
#define fi first
#define se second
#define pb push_back
#define INF 0x3f3f3f3f
#define pi 3.1415926535898
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2+1,r,rt<<1|1
#define Min(a,b,c)  min(a,min(b,c))
#define Max(a,b,c)  max(a,max(b,c))
using namespace std;
 
typedef long long ll;
typedef pair<int,int> P;
typedef unsigned long long ull;
 
const int MOD=1e9+7;
const ll LLMAX=2e18;
const int MAXN=1e6+10;
 
template<class T>
inline void read(T &DataIn)
{
    DataIn=0;    T Flag=0;   char c=getchar();
    while(!isdigit(c)){ Flag|=c=='-'; c=getchar(); }
    while(isdigit(c)){ DataIn=DataIn*10+c-'0'; c=getchar(); }
    DataIn= Flag? -DataIn: DataIn;
}
 
template<class T>
inline void write(T DataOut,char EndChar='\n')
{
    T lenth=0,number[30];
    if(DataOut==0){ putchar(48); return; }
    while(DataOut>0){ number[++lenth]=DataOut%10; DataOut/=10;}
    for(int i=lenth;i>=1;i--)    putchar(number[i]+48);
    putchar(EndChar);
}
 
//priority_queue<ll,vector<ll>,less<ll> > qd;
// priority_queue<ll, vector<ll>, greater<ll> > qu;
                     
                    const int maxn = 2e7+9;
                     
                    int n;
                    ull A,B,C;
                     
                    unsigned x,y,z; 
                    unsigned tang(){
                        unsigned t;
                        x ^=x<<16;
                        x ^=x>>5;
                        x ^=x<<1;
                        t=x;
                        x=y;
                        y=z;
                        z=t^x^y;
                        return z;
                    }
                    ull  mp[maxn],mx;
                    bool cmp(const ull &a,const ull &b){
                        return a > b;
                    }
                    ull gcd(ull a,ull b){
                        if(b==0)return a;
                        else return gcd(b,a%b);
                    }
int main(void)
{
                    FILE *fin=NULL,*fout=NULL;
                    ios::sync_with_stdio(false);    cin.tie(0);
                    //fin=freopen("D:/Project__C++/testdata.in","r",stdin);
                    //fout=freopen("D:/Project__C++/testdata.out","w",stdout);
                    int t;
                    cin>>t;
                 
                    for(int T = 1; T <= t; T ++)
                    {
                 
                        cin>>n>>A>>B>>C;    x=A,y=B,z=C;
                        
                        for(int i=0;i<n;i++)
                        {
                           mp[i] = tang();
                        }
                        int tot = min(n,15);                //由于是随机的,所以取前15个枚举就可以通过此题。
                        nth_element(mp,mp+tot,mp+n,cmp);
                         mx = 0;
                        for(int i=0; i<tot; i++){
                            for(int j=i+1; j<tot; j++){
                                mx = max(mx,  mp[i] / (gcd(mp[i],mp[j])) * mp[j]);
                            }
                        }
                        cout<<"Case #"<<T<<": "<<mx<<endl;
                    }
                 
 
    return 0;
}
nth_element

猜你喜欢

转载自www.cnblogs.com/ckxkexing/p/9434128.html