結果
| 問題 |
No.2800 Game on Tree Inverse
|
| コンテスト | |
| ユーザー |
👑 potato167
|
| 提出日時 | 2024-06-21 04:28:36 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 613 ms / 4,000 ms |
| コード長 | 2,954 bytes |
| コンパイル時間 | 2,856 ms |
| コンパイル使用メモリ | 212,976 KB |
| 最終ジャッジ日時 | 2025-02-21 23:38:52 |
|
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 64 |
ソースコード
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int D = 18;
struct node{
int sum = 0;
int depth = D - 1;
array<int, 2> to = {-1, -1};
};
int f(int a,int d){
return (a & (1 << d)) != 0;
}
vector<node> nodes;
struct binary{
int root;
int C = 0;
binary(){
root = nodes.size();
node tmp;
nodes.push_back(tmp);
}
bool get(int a){
a ^= C;
int ind = root;
while (nodes[ind].depth != -1){
int b = f(a, nodes[ind].depth);
if (nodes[ind].to[b] == -1) return false;
ind = nodes[ind].to[b];
}
return true;
}
void set(int a){
if (get(a)) return;
a ^= C;
int ind = root;
while (nodes[ind].depth != -1){
int b = f(a, nodes[ind].depth);
if (nodes[ind].to[b] == -1){
nodes[ind].to[b] = nodes.size();
node tmp;
tmp.depth = nodes[ind].depth - 1;
nodes.push_back(tmp);
}
ind = nodes[ind].to[b];
nodes[ind].sum++;
}
}
int mim(){
int ans = 0;
int ind = root;
while (ind != -1 && nodes[ind].depth != -1){
int b = f(C, nodes[ind].depth);
int d = nodes[ind].to[b];
if (d != -1 && nodes[d].sum == (1 << nodes[ind].depth)){
ans += nodes[d].sum;
ind = nodes[ind].to[1 - b];
}
else{
ind = d;
}
}
return ans;
}
vector<int> get_list(){
vector<int> res;
auto f = [&](auto self, int ind, int val) -> void {
if (ind == -1) return;
if (nodes[ind].depth == -1){
res.push_back(val ^ C);
return;
}
for (int i = 0; i < 2; i++){
self(self, nodes[ind].to[i], val + i * (1 << nodes[ind].depth));
}
};
f(f, root, 0);
return res;
}
};
int main(){
int N;
cin >> N;
vector<vector<int>> G(N);
for (int i = 0; i < N - 1; i++){
int a, b;
cin >> a >> b;
a--, b--;
G[a].push_back(b);
G[b].push_back(a);
}
vector<int> order = {0}, pare(N, -1);
pare[0] = -2;
for (int i = 0; i < N; i++){
int a = order[i];
for (auto x : G[a]) if (pare[x] == -1){
order.push_back(x);
pare[x] = a;
}
}
vector<binary> dp(N);
vector<int> val(N), ans, wei(N, 1);
for (int i = N - 1; i >= 0; i--){
int a = order[i];
int ind = -1;
int sum = 0;
for (auto x : G[a]) if (pare[x] == a){
sum ^= val[x];
wei[a] += wei[x];
if (ind == -1 || wei[x] > wei[ind]) ind = x;
}
if (ind != -1){
dp[ind].C ^= (sum ^ val[ind]);
swap(dp[ind], dp[a]);
}
for (auto x : G[a]) if (pare[x] == a && x != ind){
dp[x].C ^= (sum ^ val[x]);
for (auto y : dp[x].get_list()){
dp[a].set(y);
}
}
dp[a].set(sum);
val[a] = dp[a].mim();
}
auto dfs = [&](auto self, int ind, int v) -> void {
for (auto x : G[ind]) if (pare[x] == ind){
v ^= val[x];
}
if (v == 0) ans.push_back(ind + 1);
for (auto x : G[ind]) if (pare[x] == ind){
self(self, x, v ^ val[x]);
}
};
dfs(dfs, 0, 0);
cout << "Alice\n";
cout << ans.size() << "\n";
sort(ans.begin(), ans.end());
for (int i = 0; i < (int)ans.size(); i++){
if (i) cout << " ";
cout << ans[i];
}
cout << endl;
return 0;
}
potato167