結果
| 問題 |
No.399 動的な領主
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2016-07-19 06:36:38 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 3,090 bytes |
| コンパイル時間 | 1,440 ms |
| コンパイル使用メモリ | 161,980 KB |
| 実行使用メモリ | 10,752 KB |
| 最終ジャッジ日時 | 2024-10-15 17:16:30 |
| 合計ジャッジ時間 | 5,321 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | WA * 19 |
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:145:22: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
145 | scanf("%d %d", &u, &v);
| ~~~~~^~~~~~~~~~~~~~~~~
main.cpp:158:22: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
158 | scanf("%d %d", &u, &v);
| ~~~~~^~~~~~~~~~~~~~~~~
ソースコード
#include <bits/stdc++.h>
using namespace std;
//**************************************************************
// link-cut tree
//**************************************************************
struct node {
node *parent = nullptr;
node *lch = nullptr;
node *rch = nullptr;
bool reversed = false;
int size = 1;
long long sum = 1;
long long val = 1;
long long lazy = 0;
};
int size(node *x) {
if (x == nullptr) return 0;
return x->size;
}
long long sum(node *x) {
if (x == nullptr) return 0;
return x->sum + x->lazy * size(x);
}
void update(node *x) {
if (x == nullptr) return;
x->size = 1 + size(x->lch) + size(x->rch);
x->sum = x->val + sum(x->lch) + sum(x->rch);
}
void push(node *x) {
if (x == nullptr) return;
if (!x->reversed && x->lazy == 0) return;
for (node *y : { x->lch, x->rch }) if (y != nullptr) {
y->reversed ^= x->reversed;
y->lazy += x->lazy;
}
if (x->reversed) swap(x->lch, x->rch);
x->reversed = false;
x->val += x->lazy;
x->lazy = 0;
update(x);
}
//**************************************************************
// link-cut tree basic operation
//**************************************************************
enum { LEFT, RIGHT };
bool is_root(node *x) {
return x->parent == nullptr || (x->parent->lch != x && x->parent->rch != x);
}
int parent_direction(node *x) {
if (is_root(x)) return -1;
return x->parent->rch == x ? LEFT : RIGHT;
}
void connect(node *child, node *parent, int dir) {
if (parent != nullptr && dir != -1) (dir == RIGHT ? parent->lch : parent->rch) = child;
if (child != nullptr) child->parent = parent;
}
void raise(node *x) {
node *y = x->parent;
node *z = y->parent;
int xdir = parent_direction(x);
int ydir = parent_direction(y);
connect(xdir == LEFT ? x->lch : x->rch, y, xdir);
connect(y, x, !xdir);
connect(x, z, ydir);
update(y);
update(x);
update(z);
}
void splay(node *x) {
while (!is_root(x)) {
push(x->parent->parent);
push(x->parent);
push(x);
if (is_root(x->parent)) {
raise(x);
} else if (parent_direction(x) == parent_direction(x->parent)) {
raise(x->parent);
raise(x);
} else {
raise(x);
raise(x);
}
}
update(x);
}
void expose(node *x) {
for (node *y = x, *rch = nullptr; y != nullptr; y = y->parent) {
splay(y);
y->rch = rch;
rch = y;
update(y);
}
splay(x);
}
void cut(node *x) {
expose(x);
x->lch->parent = nullptr;
x->lch = nullptr;
update(x);
}
void link(node *x, node *p) {
expose(x);
expose(p);
x->parent = p;
p->rch = x;
update(x);
update(p);
}
void evert(node *x) {
expose(x);
x->rch = x->lch;
x->lch = nullptr;
if (x->rch != nullptr) x->rch->reversed ^= 1;
update(x);
}
node *tr[101010];
int main() {
int n;
cin >> n;
for (int i = 0; i < n; i++) tr[i] = new node();
for (int i = 0; i < n - 1; i++) {
int u, v;
scanf("%d %d", &u, &v);
u--;
v--;
evert(tr[u]);
link(tr[v], tr[u]);
}
long long ans = 0;
int Q;
cin >> Q;
while (Q--) {
int u, v;
scanf("%d %d", &u, &v);
u--;
v--;
evert(tr[u]);
expose(tr[v]);
ans += sum(tr[v]);
tr[v]->lazy++;
}
cout << ans << endl;
}