牛客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; }
skr