kmjp's blog

競技プログラミング参加記です

yukicoder : No.1419 Power Moves

これは割とすんなり。
https://yukicoder.me/problems/no/1419

問題

0~(N-1)の番号が振られたNマスが円環状につながっている。
ここで、0番のマスにあるコマをK回動かす。
i回目のステップでは、2^(i-1)だけ等確率で時計回りまたは反時計回りに移動する。
最後各マスに止まる確率はいくつか。

解法

円環を無視すると、-(2^K-1)~(2^K-1)の範囲の奇数マスに等確率で止まる。
よっておおむね(偶奇を除けば)だいたい同じ確率で止まる。
あとは端数分だけ処理すればよい。

int N,K;
const ll mo=1000000007;

ll modpow(ll a, ll n = mo-2,ll mo=mo) {
	ll r=1;a%=mo;
	while(n) r=r*((n%2)?a:1)%mo,a=a*a%mo,n>>=1;
	return r;
}

ll pat[101010];

void solve() {
	int i,j,k,l,r,x,y; string s;
	
	cin>>N>>K;
	ll del=(modpow(2,K,N)+N-1)%N;
	ll num=((2*mo+modpow(2,K)-1)-del)%mo;
	FOR(i,N) {
		pat[(2*N-del+i*2)%N]+=(num*modpow(N)+(i<=(del%N)))%mo*modpow(modpow(2,K))%mo;
	}
	FOR(i,N) cout<<pat[i]%mo<<endl;
	
	
}

まとめ

シンプルな設定で良いね。