$[ Luogu 4626 ]$ 一道水題$ II$
阿新 • • 發佈:2018-10-04
() init 常數 esc 因數 name tps printf 毫秒
除\(p_i\)至\(0\),那麽合法的除的次數就是最高冪次的指數。
\(\\\)
\(Description\)
求一個能被\([1,n]\) 內所有數整除的最小數字,並對 \(100000007\) 取模
- \(N\in [1,10^8]\)
\(\\\)
\(Solution\)
一道卡常好題 好吧是我常數太大了
考慮將限制區間內所有數質因數分解,對每一個質因子\(i\)記錄下\(t_i\)表示,這個質因子在區間內任意一個數裏,出現的最高冪次,那麽答案就應該是每個質因子對應的最高冪之積。
質數可以線性篩 註意常數別寫醜了 ,考慮如何求每一個質數的最高次冪。考慮將上限\(N\)除掉一次質因數\(p_i\),得到的數就代表原來那些含\(p_i\)的數的個數。於是一直將\(N\)
然後我寫了個快速冪就\(T\)了......註意到叠代的同時是可以記錄這個最高次冪的結果的,所以可以去掉快速冪的\(log\)復雜度雖然只快了幾十毫秒依然卡著時限
\(\\\)
\(Code\)
#include<cmath> #include<cstdio> #include<cctype> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define N 100000010 #define R register #define mod 100000007ll using namespace std; typedef long long ll; bool vis[N]; int n,prm[N>>3]; inline void init(int n){ for(R int i=2;i<=n;++i){ if(!vis[i]) prm[++prm[0]]=i; for(R int j=1,k;j<=prm[0]&&(k=prm[j]*i)<=n;++j){ vis[k]=1; if(i%prm[j]==0) break; } } } inline ll qpow(ll x,ll t){ ll res=1; while(t){ if(t&1) (res*=x)%=mod; (x*=x)%=mod; t>>=1; } return res; } int main(){ scanf("%d",&n); init(n); R ll tmp,res,ans=1; for(R int i=1;i<=prm[0];++i){ tmp=(ll)n; res=1; while(tmp>=prm[i]) (res*=prm[i])%=mod,tmp/=prm[i]; (ans*=res)%=mod; } printf("%lld\n",ans); return 0; }
$[\ Luogu\ 4626\ ]$ 一道水題$\ II$