問題はこちら
No.368 LCM of K-products - yukicoder
まずLCMについて考える
一般に、と素因数分解される数に対して
となる
ここでであることから求めるべきは
となる。ただしmaxは#I=KとなるようなI全体を動く
は明らかに「の大きい方からK個の和」となるのでこれを求めれば良い
素数ごとに指数が大きいものからK個を取ってきて……と実装するのが意外とめんどくさい
d[3000][40]; //この配列のd[*][0]に素数を //d[*][n+1]に、d[*][0]^nを因数に持つようなa[i]の個数を、それぞれ保存する //10^9以下の数が1000個なので、そこに登場する素因数は高々3000個 //(最初の3000個の素数の積は10^9000より大きい) //また2^30>10^9なので、その指数は30以下 ans,n,k,a,i,j,p,t,m=1e9+7; long pow(a,n){return n?a*pow(a,n-1)%m:1;} void push(p,t){ //素数pを新たにdに追加する d[j][0]=p; d[j][1]=i; d[j][t+1]=1; j++; } int main(){ scanf("%d%d",&n,&k); for(i=0;i<n;i++){ scanf("%d",&a); for(j=0;d[j][0];j++){ //既にdにある素数で割れるかどうかチェック for(t=0;a%d[j][0]<1;t++)a/=d[j][0]; d[j][t+1]++; } if(a>1){ //dにあるもの以外の素因数を探す for(p=2;a>=p*p;p++){ for(t=0;a%p<1;t++)a/=p; if(t)push(p,t); //見つけたら追加 } if(a>1)push(a,1); } } ans=1; for(i=0;d[i][0];i++){ //各iごとに指数が大きな方からk個の和を求める p=t=0; for(j=30;t<k;){ if(d[i][j]){ d[i][j]--; t++; p+=j-1; }else j--; } ans=ans*pow(d[i][0],p)%m; } printf("%d",ans); return 0; }
ひとまず短くする
d[3000][40]; x,n,i,j,k,t,m=1e9+7; long p(a,n){return n?a*p(a,n-1)%m:1;} f(s,t,y){ //素数sを探して、t番目をinc(見つからなければ末尾に追加する) for(y=0;d[++y][0]&&d[y][0]-s;); d[y][0]=s; d[y][t]++; } main(s){ for(scanf("%*d%d",&n);~scanf("%d",&s);s>1&&f(s,1))for(k=1;s>=++k*k;t&&f(k,t))for(t=0;s%k<1;++t)s/=k; //sがk^tで割れるならf(k,t)としてdにデータを追加 //f(s,0)のようなものをしないようにすることで、indexのずれを解消 for(s=1;x=d[++i][0]?:!printf("%d",s);s=s*p(x,k)%m)for(k=t=0,j=30;t<n&&j;)d[i][j]--?t++,k+=j:--j; }
頑張って短くする
d[3000][40]; x,n,i,j,k,t,m=1e9+7; long p(a,n){return n?a*p(a,n-1)%m:1;} f(s,x,y){ for(t=y=0;d[++y][0]&&d[y][0]-s;); //グローバル変数tの初期化もここに紛れ込ませる d[y][0]=s; d[y][x]++; } main(s){ for(scanf("%*d%d",&n);~scanf("%d",&s);f(s,1))for(k=2;s%k<1?s/=k,++t:(t&&f(k,t),s>k*k++);); //s>1&&f(s,1)をやめた(1が入っても答えに影響しない) //また後ろのfor文を圧縮し、kをincするタイミングを変えることで1文字短縮 for(s=1;x=d[++i][0]?:!printf("%d",s);s=s*p(x,k)%m)for(k=t=0,j=30;t<n&&d[i][j]--?t++,k+=j:--j;); //後ろのfor文を少しいじって短縮 }
326B
(2016/05/30追記)
ポインタを使えばもっと縮められた
d['~~'][40]; *q,n,i,k,t,m=1e9+7; long p(a,n){return n?a*p(a,n-1)%m:1;} f(s,x){ for(q=d;*(q+=40)&&*q-s;); q[x]++; *q=s; } main(s){ for(scanf("%*d%d",&n);~scanf("%d",&i);f(i,1))for(k=2;i%k<1?i/=k,++t:(t&&f(k,t),t=0,i>k*k++);); for(q=d;*(q+=40);s=s*p(*q,k)%m)for(k=t=0,i=30;t<n&&q[i]--?t++,k+=i:--i;); i=!printf("%d",s); }
307B