ARC046 C - 掛け算
やり直し
解法
Bが109乗なので愚直にシミュレーションするとTLEになってしまう。aを昇順に並び替えつつ、何回かシミュレーションをすると a[0] * A >= a[N-1] となる時が来る。こうなったらN周期で同じ列が現れる状態になる。周期的になるまでは高々N*log(max(a))回シミュレーションすれば良い。
周期的になる状態ができたら(残りB'回とする)あとはi < B' % Nを満たすa[i]はB'/N+1回、i >= B' % Nを満たすa[i]はB'/N回、Aをかければ良いとわかる。
愚直にAを掛け算するとTLEする可能性があるので、高速累乗すればACできる。
コード
#include <algorithm> #include <cstdio> #include <iostream> #include <map> #include <cmath> #include <queue> #include <set> #include <sstream> #include <stack> #include <string> #include <vector> #include <stdlib.h> #include <stdio.h> #include <bitset> #include <cstring> using namespace std; #define FOR(I,A,B) for(int I = (A); I < (B); ++I) #define CLR(mat) memset(mat, 0, sizeof(mat)) typedef long long ll; const int mod = 1e9 + 7; int main() { ios::sync_with_stdio(false); cin.tie(0); ll N, A, B; cin >> N >> A >> B; ll a[N]; FOR(i,0,N) cin >> a[i]; sort(a, a + N); if(A == 1) { FOR(i,0,N) cout << a[i] % mod << endl; return 0; } ll k = 0; while(B) { sort(a, a + N); if(a[0] * A >= a[N-1]) break; a[0] *= A; B--; } sort(a, a + N); // 周期的になる前に終わる if(B == 0) FOR(i,0,N) cout << a[i] % mod << endl; // 周期的になる else { FOR(i,0,N) a[i] %= mod; // B / N 回 A倍する FOR(i,B%N,N) { ll C = B / N; ll AA = A % mod; while(C) { if(C&1) a[i] = (a[i] * AA) % mod; AA = (AA * AA) % mod; C >>= 1; } } FOR(i,0,B%N) { ll C = B / N + 1; ll AA = A % mod; while(C) { if(C&1) a[i] = (a[i] * AA) % mod; AA = (AA * AA) % mod; C >>= 1; } } FOR(i,0,N) { cout << a[(i+B%N)%N] << endl; } } return 0; }