読者です 読者をやめる 読者になる 読者になる

土下座しながら探索中

主に競技プログラミング

SRM 652 Div1 250 : ThePermutationGame

問題概要:
これまた備忘録なので略

解法:
1からNまでの周期が存在するので(<=ノートに書いてたらそんな感じ、直感的に)
1からNまでの最小公倍数を求めれば良い(<=さっきのことがわかればそうなるでしょうね)
1からNまでで存在する素数を列挙し、それらをNを超えない最大のべき乗をもとめる(<=はい、)
あとはそれらを掛け合わせる

普通に1からNまでループ回して a / __gcd(a,b) * b みたいなことしたら mod とってるおかげでうまくいかなかった
a * mod_inv(__gcd(a,b),mod) * b ともしてみたけどだめだったので上のような方法にした

コード:

const ll mod = 1000000007LL;
const int  MAX = 1000000;
bool isntprime[MAX+1]; 
vector<int> prime;

class ThePermutationGame {
public:
	
  void init(){
    isntprime[0] = isntprime[1] = true;
    int j;	
    for(int i=2;i<= MAX;i++)if(!isntprime[i])for(prime.push_back(i),j=2*i;j<=MAX;j+=i)isntprime[j] = true;
  }  

  int findMin(int N) {
    init();
    ll answer = 1;
    rep(i,prime.size()){
      if( prime[i] > N ) break;
      ll multi = prime[i];
      ll coef  = prime[i];
      while( multi*coef <= (ll)N ) multi *= coef;
      ( answer *= multi ) %= mod;
    }
    return answer;
  }
};