結果
問題 | No.1665 quotient replace |
ユーザー | 👑 AngrySadEight |
提出日時 | 2021-09-03 22:26:20 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 395 ms / 3,000 ms |
コード長 | 16,915 bytes |
コンパイル時間 | 2,277 ms |
コンパイル使用メモリ | 194,236 KB |
実行使用メモリ | 15,016 KB |
最終ジャッジ日時 | 2024-05-09 04:59:08 |
合計ジャッジ時間 | 9,529 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 12 ms
7,128 KB |
testcase_01 | AC | 12 ms
7,084 KB |
testcase_02 | AC | 12 ms
7,168 KB |
testcase_03 | AC | 12 ms
7,124 KB |
testcase_04 | AC | 12 ms
7,132 KB |
testcase_05 | AC | 12 ms
7,168 KB |
testcase_06 | AC | 15 ms
7,168 KB |
testcase_07 | AC | 12 ms
7,172 KB |
testcase_08 | AC | 13 ms
7,276 KB |
testcase_09 | AC | 23 ms
7,444 KB |
testcase_10 | AC | 139 ms
9,760 KB |
testcase_11 | AC | 301 ms
13,184 KB |
testcase_12 | AC | 42 ms
7,808 KB |
testcase_13 | AC | 392 ms
15,016 KB |
testcase_14 | AC | 391 ms
14,944 KB |
testcase_15 | AC | 395 ms
14,888 KB |
testcase_16 | AC | 384 ms
14,888 KB |
testcase_17 | AC | 395 ms
14,952 KB |
testcase_18 | AC | 13 ms
7,236 KB |
testcase_19 | AC | 12 ms
7,084 KB |
testcase_20 | AC | 13 ms
7,296 KB |
testcase_21 | AC | 12 ms
7,168 KB |
testcase_22 | AC | 12 ms
7,100 KB |
testcase_23 | AC | 12 ms
7,100 KB |
testcase_24 | AC | 12 ms
7,148 KB |
testcase_25 | AC | 12 ms
7,168 KB |
testcase_26 | AC | 12 ms
7,196 KB |
testcase_27 | AC | 14 ms
7,168 KB |
testcase_28 | AC | 23 ms
7,536 KB |
testcase_29 | AC | 34 ms
7,784 KB |
testcase_30 | AC | 173 ms
11,192 KB |
testcase_31 | AC | 257 ms
13,212 KB |
testcase_32 | AC | 283 ms
12,968 KB |
testcase_33 | AC | 114 ms
9,344 KB |
testcase_34 | AC | 232 ms
11,636 KB |
testcase_35 | AC | 215 ms
11,264 KB |
testcase_36 | AC | 223 ms
11,772 KB |
testcase_37 | AC | 199 ms
11,116 KB |
testcase_38 | AC | 240 ms
11,992 KB |
testcase_39 | AC | 170 ms
10,644 KB |
testcase_40 | AC | 170 ms
10,612 KB |
testcase_41 | AC | 173 ms
10,400 KB |
testcase_42 | AC | 12 ms
7,196 KB |
testcase_43 | AC | 12 ms
7,156 KB |
ソースコード
#include <bits/stdc++.h> using namespace std; #define rep(i,n) for(int i = 0; i < (int)(n); i++) #define repr(i,n) for(int i = (int)(n); i >= 0; i--) #define all(v) v.begin(),v.end() #define mod1 1000000007 #define mod2 998244353 typedef long long ll; vector<ll> bitconversion(ll i, ll n, ll N){ //数字iをn進数にして,長さNの配列にして返す。 //例えば,bitconversion(33,3,4)={1,0,2,0}。 ll x = 1; rep(j,N){ x *= n; } vector<ll> vec(N); rep(j,N){ x /= n; vec[j] = i / x; i -= x * vec[j]; } return vec; } int ctoi(char c){ //char型の1桁の数をint型に変える。 switch (c){ case '0': return 0; case '1': return 1; case '2': return 2; case '3': return 3; case '4': return 4; case '5': return 5; case '6': return 6; case '7': return 7; case '8': return 8; case '9': return 9; default: return 0; } } vector<int> topological_sort(vector<vector<int> > &connection, vector<int> &count, int N){ //vectorをトポロジカルソートして返す。 //connectionにはそこからたどり着くことの出来る頂点の番号をあらかじめ入れておく。 //countにはその頂点に入ってくる頂点の数を入れておく。 vector<int> ans(0); queue<int> que; for (int i = 0; i < N; i++){ if (count[i] == 0){ que.push(i); } } while(que.size() != 0){ int v = que.front(); que.pop(); for (int i = 0; i < connection[v].size(); i++){ count[connection[v][i]] -= 1; if (count[connection[v][i]] == 0){ que.push(connection[v][i]); } } ans.push_back(v); } return ans; } struct union_find{ vector<int> par; vector<int> rank; vector<int> siz; vector<int> siz2; union_find(int N) : par(N), rank(N), siz(N), siz2(N){ rep(i,N){ par[i] = i; rank[i] = 0; siz[i] = 1; siz2[i] = 0; } } //宣言パート。union_findを宣言する時は,例えばunion_find tree(N)のようにする。 int root(int x){ if (par[x] == x){ return x; } return par[x] = root(par[x]); } //頂点に対して,その根となる頂点の番号を返す。 void unite(int x, int y){ int rx = root(x); int ry = root(y); if (rx == ry){ siz2[rx]++; return; } if (rank[rx] < rank[ry]){ par[rx] = ry; siz[ry] += siz[rx]; siz2[ry] += siz2[rx]; siz2[ry]++; } else{ par[ry] = rx; siz[rx] += siz[ry]; siz2[rx] += siz2[ry]; siz2[rx]++; if (rank[rx] == rank[ry]) rank[rx]++; } } //頂点xとyをくっつけてやる。計算量削減のため,それぞれの木の「高さ」(rank)をカウントしておいて, //その高さの高い方に低い方をくっつけてやるようにする。 bool same(int x, int y){ int rx = root(x); int ry = root(y); return rx == ry; } //頂点xとyが同じ木に属するかを判定する。 int size(int x){ return siz[root(x)]; } //頂点xが含まれる木のサイズ。 int size2(int x){ return siz2[root(x)]; } }; ll gcd(ll a, ll b){ //aとbの最大公約数。 ll r,temp; if (a < b){ temp = a; a = b; b = temp; } while ( (r = a % b) != 0){ a = b; b = r; } return b; } ll iterative_square_method(ll i, vector<ll> &vec, ll N, ll mod){ //繰り返し二乗法。iのX乗をmodで割った余りを求める。 //なお,Xは,事前にmoddividing関数で長さNの二進数vector(vec)に直しておく必要がある。 //例えば,2の100000乗をmod1e9+7で求めたいときは, //iterative_square_method(2,moddividing(100000,2,30),30,1000000007)のように書けば良い。 ll ans = 1; rep(j,N){ if (vec[N - 1 - j] == 1) ans = (ans * i) % mod; i = (i * i) % mod; } return ans; } double iterative_square_method2(double X, vector<ll> &vec, ll N){ double ans = 1; rep(j,N){ if (vec[N - 1 - j] == 1) ans = ans * X; X = X * X; } return ans; } ll moddividing(ll x,ll y){ //x÷yをmod1e9+7で求める。 vector<ll> vec(30); rep(i,30){ vec[i] = y; y = y * y % 1000000007; } ll c = x; c = c * vec[0] % 1000000007; c = c * vec[2] % 1000000007; c = c * vec[9] % 1000000007; c = c * vec[11] % 1000000007; c = c * vec[14] % 1000000007; c = c * vec[15] % 1000000007; c = c * vec[17] % 1000000007; c = c * vec[19] % 1000000007; c = c * vec[20] % 1000000007; c = c * vec[23] % 1000000007; c = c * vec[24] % 1000000007; c = c * vec[25] % 1000000007; c = c * vec[27] % 1000000007; c = c * vec[28] % 1000000007; c = c * vec[29] % 1000000007; return c; } ll moddividing2(ll x,ll y){ //x÷yをmod998244353で求める。 vector<ll> vec(30); rep(i,30){ vec[i] = y; y = y * y % 998244353; } ll c = x; c = c * vec[0] % 998244353; c = c * vec[1] % 998244353; c = c * vec[2] % 998244353; c = c * vec[3] % 998244353; c = c * vec[4] % 998244353; c = c * vec[5] % 998244353; c = c * vec[6] % 998244353; c = c * vec[7] % 998244353; c = c * vec[8] % 998244353; c = c * vec[9] % 998244353; c = c * vec[10] % 998244353; c = c * vec[11] % 998244353; c = c * vec[12] % 998244353; c = c * vec[13] % 998244353; c = c * vec[14] % 998244353; c = c * vec[15] % 998244353; c = c * vec[16] % 998244353; c = c * vec[17] % 998244353; c = c * vec[18] % 998244353; c = c * vec[19] % 998244353; c = c * vec[20] % 998244353; c = c * vec[21] % 998244353; c = c * vec[22] % 998244353; c = c * vec[24] % 998244353; c = c * vec[25] % 998244353; c = c * vec[27] % 998244353; c = c * vec[28] % 998244353; c = c * vec[29] % 998244353; return c; } struct segtree{ //セグメントツリー。いろんな機能があるよ。やったね。 vector<ll> vec; segtree(ll N) : vec(N){ rep(i,N){ vec[i] = 0; } } //初期化。セグメントツリーの正体はvectorである。 //バグが発生する可能性があるため,サイズNは(用意したいセグ木の長さ)*2よりも大きい2の累乗数で宣言してやる。 void make(ll k, ll a, ll N){ //0_indexed k += (N / 2); vec[k] = a; } //セグメントツリーのk番目の要素をaに変える。 void sum_update(ll k, ll a, ll N){ //0_indexed k += (N / 2); vec[k] = a; while(k > 1){ k = k / 2; vec[k] = vec[k * 2] + vec[k * 2 + 1]; } } //セグメントツリー上で和の計算を行う上での前処理。k番目の要素をaに変更して,なおかつ和の計算の前処理を行う。 void max_update(ll k, ll a, ll N){ //0_indexed k += (N / 2); vec[k] = a; while(k > 1){ k = k / 2; vec[k] = max(vec[k * 2], vec[k * 2 + 1]); } } //セグメントツリー上で最大値を求める上での前処理。k番目の要素をaに変更して,なおかつ最大値を求める前処理を行う。 void min_update(ll k, ll a, ll N){ //0_indexed k += (N / 2); vec[k] = a; while(k > 1){ k = k / 2; vec[k] = min(vec[k * 2], vec[k * 2 + 1]); } } //セグメントツリー上で最小値を求める上での前処理。k番目の要素をaに変更して,なおかつ最小値を求める前処理を行う。 ll min_query(ll a, ll b, ll k, ll l, ll r){ // min_query(a,b,1,0,N / 2) a,b,l,r=0_indexed if (r <= a || b <= l) return 1000000000; if (a <= l && r <= b) return vec[k]; ll vl = min_query(a, b, k * 2, l, (l + r) / 2); ll vr = min_query(a, b, k * 2 + 1, (l + r) / 2, r); return min(vl,vr); } //セグメントツリー上で最小値を求める。半開区間[a,b)(a,bは0_indexed)における最小値を求めてやる。 //k,l,rは固定で,k=1,l=0,r=N/2として良い。 ll check(ll i, ll N){ return vec[i + N / 2]; } //i番目の要素を確認する。 ll max_query(ll a, ll b, ll k, ll l, ll r){ // max_query(a,b,1,0,N / 2) a,b,l,r=0_indexed if (r <= a || b <= l) return -100000000000000000; if (a <= l && r <= b) return vec[k]; ll vl = max_query(a, b, k * 2, l, (l + r) / 2); ll vr = max_query(a, b, k * 2 + 1, (l + r) / 2, r); return max(vl,vr); } //セグメントツリー上で最大値を求める。半開区間[a,b)(a,bは0_indexed)における最大値を求めてやる。 //k,l,rは固定で,k=1,l=0,r=N/2として良い。 ll sum_query(ll a, ll b, ll k, ll l, ll r){ // sum_query(a,b,1,0,N / 2) a,b,l,r=0_indexed if (r <= a || b <= l) return 0; if (a <= l && r <= b) return vec[k]; ll vl = sum_query(a, b, k * 2, l, (l + r) / 2); ll vr = sum_query(a, b, k * 2 + 1, (l + r) / 2, r); return vl + vr; } //セグメントツリー上で和を求める。半開区間[a,b)(a,bは0_indexed)における和を求めてやる。 //k,l,rは固定で,k=1,l=0,r=N/2として良い。 }; char itoc(int c){ //int型の0から25までの値cを,(c+1)番目のchar型アルファベット1文字に変更してやる。 switch (c){ case 0: return 'a'; case 1: return 'b'; case 2: return 'c'; case 3: return 'd'; case 4: return 'e'; case 5: return 'f'; case 6: return 'g'; case 7: return 'h'; case 8: return 'i'; case 9: return 'j'; case 10: return 'k'; case 11: return 'l'; case 12: return 'm'; case 13: return 'n'; case 14: return 'o'; case 15: return 'p'; case 16: return 'q'; case 17: return 'r'; case 18: return 's'; case 19: return 't'; case 20: return 'u'; case 21: return 'v'; case 22: return 'w'; case 23: return 'x'; case 24: return 'y'; case 25: return 'z'; default: return 'a'; } } ll kruskal(vector<pair<ll,pair<int,int> > > &connect, union_find tree){ //クラスカル法で,1辺を結ぶ2頂点の番号とその辺の長さが与えられた場合に //最小全域木を作る場合の辺の長さの総和を求める。 //connect関数には,「1辺の長さ」「2頂点の番号」をあらかじめ入れておく。 ll ans = 0; for (ll i = 0; i < connect.size(); i++){ if (!tree.same(connect[i].second.first, connect[i].second.second)){ ans += connect[i].first; tree.unite(connect[i].second.first, connect[i].second.second); } } return ans; } void dijkstra(vector<vector<pair<ll,ll> > > &G, ll s, vector<ll> &dis) { //ダイクストラ法。sを始点としたときの,最短距離を求める。 //ここでは,Gに「第一要素=行き先,第二要素=コスト」として,無効グラフを考える。 //Nには構成されるグラフの頂点の数が入る。 //計算量は,辺の数をE,頂点の数をVとして,O(ElogV)である。 //priority_queueの要素は「第一要素=距離,第二要素=頂点の番号」だから注意! priority_queue<pair<ll,ll>, vector<pair<ll,ll> >, greater<pair<ll,ll> > > pque; dis[s] = 0; pque.push(pair<ll,ll>(dis[s], s)); while(!pque.empty()){ pair<ll,ll> p = pque.top(); pque.pop(); ll v = p.second; if (dis[v] < p.first) continue; for (int i = 0; i < G[v].size(); i++){ if (dis[G[v][i].first] > dis[v] + G[v][i].second){ dis[G[v][i].first] = dis[v] + G[v][i].second; pque.push(pair<ll,ll>(dis[G[v][i].first], G[v][i].first)); } } } } vector<vector<ll> > matrix_exponentiation(vector<vector<ll> > &M, vector<ll> &bin, ll N, ll K, ll mod){ //行列累乗。N*N行列MのX乗を求める。ただし,Xは,事前にbitconversion関数で2進数に変えておき,その配列binを渡す必要あり。 //NにはMの行列のサイズを,Kにはbin配列のサイズを渡す。また,modを取る場合は変数modにその値を渡す。 vector<vector<ll> > matrix(N, vector<ll>(N)); for (ll i = 0; i < N; i++){ for (ll j = 0; j < N; j++){ matrix[i][j] = M[i][j]; } } vector<vector<ll> > ans_old_matrix(N, vector<ll>(N)); for (ll i = 0; i < N; i++){ for (ll j = 0; j < N; j++){ if (i == j) ans_old_matrix[i][j] = 1; else ans_old_matrix[i][j] = 0; } } vector<vector<ll> > ans_new_matrix(N, vector<ll>(N)); for (ll i = 0; i < N; i++){ for (ll j = 0; j < N; j++){ ans_new_matrix[i][j] = 0; } } vector<vector<ll> > new_matrix(N, vector<ll>(N)); for (ll i = 0; i < N; i++){ for (ll j = 0; j < N; j++){ new_matrix[i][j] = 0; } } for (ll x = 0; x < K; x++){ if (bin[K - 1 - x] == 1){ for (ll i = 0; i < N; i++){ for (ll j = 0; j < N; j++){ for (ll k = 0; k < N; k++){ ans_new_matrix[i][j] = (ans_new_matrix[i][j] + (ans_old_matrix[i][k] * matrix[k][j]) % mod) % mod; } } } for (ll i = 0; i < N; i++){ for (ll j = 0; j < N; j++){ ans_old_matrix[i][j] = ans_new_matrix[i][j]; ans_new_matrix[i][j] = 0; } } } for (ll i = 0; i < N; i++){ for (ll j = 0; j < N; j++){ for (ll k = 0; k < N; k++){ new_matrix[i][j] = (new_matrix[i][j] + (matrix[i][k] * matrix[k][j]) % mod) % mod; } } } for (ll i = 0; i < N; i++){ for (ll j = 0; j < N; j++){ matrix[i][j] = new_matrix[i][j]; new_matrix[i][j] = 0; } } } return ans_old_matrix; } void bellman_ford(vector<ll> &from, vector<ll> &to, vector<ll> &cost, vector<ll> &dis, ll v, ll N, ll M, bool &negative){ //ベルマンフォード法。 //頂点fromから頂点toまでの長さcostの辺が,M本張られている。頂点数はN。 //このもとで,始点vからの最短距離disを求めることにする。 //負の閉路がある場合はnegativeがtrueになる。 vector<bool> hasroute(N, false); hasroute[v] = true; vector<bool> nega(N, false); for (ll i = 0; i < N; i++){ bool update = false; for (ll j = 0; j < M; j++){ if (dis[to[j]] > dis[from[j]] + cost[j]){ dis[to[j]] = dis[from[j]] + cost[j]; if (hasroute[from[j]]) hasroute[to[j]] = true; update = true; if (i == N - 1){ nega[to[j]] = true; } } } if (!update){ break; } } for (ll i = 0; i < N; i++){ for (ll j = 0; j < M; j++){ if (hasroute[from[j]] && nega[from[j]]) nega[to[j]] = true; } } if (hasroute[N - 1] && nega[N - 1]) negative = true; } int main(){ int N; cin >> N; vector<int> A(N); for (int i = 0; i < N; i++){ cin >> A[i]; } vector<int> prime(1000003, 1); for (int i = 2; i < 1000003; i++){ if (prime[i] == 1){ for (int j = 1; j * i < 1000003; j++){ prime[i * j] = i; } } } /*for (int i = 1; i <= 10; i++){ cout << prime[i] << " "; } cout << endl;*/ vector<int> num_prime(N); for (int i = 0; i < N; i++){ int now = A[i]; int sum = 0; while(true){ if (now == 1){ break; } now = now / prime[now]; sum++; } num_prime[i] = sum; } int ans = 0; for (int i = 0; i < N; i++){ ans = ans ^ num_prime[i]; } if (ans == 0) cout << "black" << endl; else cout << "white" << endl; }