結果
| 問題 |
No.74 貯金箱の退屈
|
| コンテスト | |
| ユーザー |
peroon
|
| 提出日時 | 2019-04-19 14:05:21 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 2 ms / 5,000 ms |
| コード長 | 2,880 bytes |
| コンパイル時間 | 2,002 ms |
| コンパイル使用メモリ | 182,904 KB |
| 実行使用メモリ | 6,944 KB |
| 最終ジャッジ日時 | 2024-09-22 11:28:31 |
| 合計ジャッジ時間 | 2,967 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 30 |
ソースコード
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define FOR(i,a,b) for(ll i=(a);i<(b);++i)
#define ALL(v) (v).begin(), (v).end()
#define p(s) cout<<(s)<<endl
#define p2(s, t) cout << (s) << " " << (t) << endl
#define br() p("")
#define pn(s) cout << (#s) << " " << (s) << endl
#define p_yes() p("Yes")
#define p_no() p("No")
const ll mod = 1e9 + 7;
const ll inf = 1e18;
struct UnionFind{
vector<ll> parent;
UnionFind(ll sz){
parent.resize(sz);
reset();
}
void reset(){
FOR(i, 0, parent.size()){
parent[i] = i;
}
}
void unite(ll a, ll b){
if(a>b){
swap(a, b);
}
ll rootA = findRoot(a);
ll rootB = findRoot(b);
if(rootA>rootB){
swap(rootA, rootB);
}
if(rootA==rootB){
return;
}else{
// 小さい方を親にする
parent[rootB] = rootA;
}
}
ll findRoot(ll a){
if(parent[a]==a){
return a;
}else{
return parent[a] = findRoot(parent[a]);
}
}
map<ll, vector<ll> > getGroups(){
map<ll, vector<ll> > G;
FOR(i, 0, parent.size()){
ll r = findRoot(i);
G[r].push_back(i);
}
return G;
}
};
int main(){
cin.tie(0);
ios::sync_with_stdio(false);
// input
ll N;
cin >> N;
vector<ll> D(N);
FOR(i, 0, N){
cin >> D.at(i);
}
vector<ll> W(N);
FOR(i, 0, N){
cin >> W.at(i);
}
auto uf = UnionFind(N);
// 1枚だけひっくり返せるか
vector<bool> F(N);
FOR(i, 0, N){
ll v = D[i];
// 時計回り
ll a = (i+v)%N;
// 反時計回り
ll b = (i-v)%N;
if(b<0) b+= N;
if(a==b){
F[a] = true;
}else{
uf.unite(a, b);
}
}
// グループごとに見ていく
auto groups = uf.getGroups();
for(auto p : groups){
vector<ll> group = p.second;
// vprint(group);
if(group.size()==1){
ll i = group[0];
if(W[i]==0){
if(!F[i]){
p_no();
return 0;
}
}
}
else{
// 1枚フリップできるものがあるか
bool flippable = false;
for(ll i : group){
if(F[i]) flippable = true;
}
ll back_num = 0;
for(ll i : group){
if(W[i]==0) back_num++;
}
if(!flippable){
// 裏のものが偶数じゃないとアウト
if(back_num%2==1){
p_no();
return 0;
}
}
}
}
p_yes();
return 0;
}
peroon