NOIP 模擬 $32\; \rm Smooth$
阿新 • • 發佈:2021-08-07
題解
題解 \(by\;zj\varphi\)
很簡單的貪心題。
開 \(B\) 個佇列,每個佇列存最後一次乘上的數為當前佇列編號的數。
每次去所有佇列中隊首的最小值,不用開堆,因為開堆用於將所有數排序,但沒必要。
將選出的答案只向編號比它大的佇列加,因為再小的數在它自己那也能更新,這樣即可去重。
別忘了 \(1\) 也算。
Code
#include<bits/stdc++.h> #define ri register signed #define p(i) ++i namespace IO{ char buf[1<<21],*p1=buf,*p2=buf; #define gc() p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?(-1):*p1++ struct nanfeng_stream{ template<typename T>inline nanfeng_stream &operator>>(T &x) { ri f=0;x=0;register char ch=gc(); while(!isdigit(ch)) {f|=ch=='-';ch=gc();} while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=gc();} return x=f?-x:x,*this; } }cin; } using IO::cin; namespace nanfeng{ #define FI FILE *IN #define FO FILE *OUT template<typename T>inline T cmax(T x,T y) {return x>y?x:y;} template<typename T>inline T cmin(T x,T y) {return x>y?y:x;} static const int N=7e7; int prime[]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47}; int mx[N+1],prim[N],nm,B,k,cnt; bool vis[N+1]; inline void Getprime() { for (ri i(2);i<=N;p(i)) { if (!vis[i]) mx[prim[p(nm)]=i]=i; for (ri j(1);j<=nm&&prim[j]*i<=N;p(j)) { ri l=prim[j]; vis[l*i]=1,mx[l*i]=mx[i]; if (!(i%l)) break; } } } inline int main() { //FI=freopen("nanfeng.in","r",stdin); //FO=freopen("nanfeng.out","w",stdout); cin >> B >> k; Getprime(); const int PB=prime[B]; for (ri i(1);i<=N;p(i)) { if (mx[i]>PB) continue; p(cnt); if (cnt==k) {printf("%d\n",i);break;} } return 0; } } int main() {return nanfeng::main();}