結果
| 問題 |
No.235 めぐるはめぐる (5)
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2016-05-25 23:41:01 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 4,137 bytes |
| コンパイル時間 | 1,568 ms |
| コンパイル使用メモリ | 163,572 KB |
| 実行使用メモリ | 33,992 KB |
| 最終ジャッジ日時 | 2024-10-07 14:30:34 |
| 合計ジャッジ時間 | 7,399 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | WA * 3 |
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:162:42: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
162 | for (int i = 0; i < n; i++) scanf("%d", &S[i]);
| ~~~~~^~~~~~~~~~~~~
main.cpp:163:42: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
163 | for (int i = 0; i < n; i++) scanf("%d", &C[i]);
| ~~~~~^~~~~~~~~~~~~
main.cpp:168:22: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
168 | scanf("%d %d", &u, &v);
| ~~~~~^~~~~~~~~~~~~~~~~
main.cpp:181:22: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
181 | scanf("%d", &k);
| ~~~~~^~~~~~~~~~
main.cpp:185:30: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
185 | scanf("%d %d %d", &x, &y, &z);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:199:30: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
199 | scanf("%d %d", &x, &y);
| ~~~~~^~~~~~~~~~~~~~~~~
ソースコード
#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1e9 + 7;
//**************************************************************
// link-cut tree
//**************************************************************
struct node {
node *parent = nullptr;
node *lch = nullptr;
node *rch = nullptr;
bool reversed = false;
long long value;
long long sum;
long long coef;
long long sum_coef;
long long lazy = 0;
node(long long value, long long coef) {
this->value = this->sum = value;
this->coef = this->sum_coef = coef;
}
};
long long sum_coef(node *x) {
return x == nullptr ? 0 : x->sum_coef;
}
long long sum(node *x) {
return x == nullptr ? 0 : x->sum;
}
void update(node *x) {
if (x == nullptr) return;
x->sum_coef = (x->coef + sum_coef(x->lch) + sum_coef(x->rch)) % MOD;
x->sum = (x->value + sum(x->lch) + sum(x->rch)) % MOD;
}
void push(node *x) {
if (x == nullptr) return;
for (node *y : { x->lch, x->rch }) if (y != nullptr) {
y->reversed ^= x->reversed;
(y->lazy += x->lazy) %= MOD;
(y->sum += x->lazy * sum_coef(y->lch)) %= MOD;
}
if (x->reversed) swap(x->lch, x->rch);
x->reversed = false;
(x->value += x->lazy * x->coef) %= MOD;
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);
}
}
push(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);
}
//**************************************************************
// main
//**************************************************************
vector<int> g[202020];
node *tr[202020];
void dfs(int curr, int prev) {
for (int next : g[curr]) if (next != prev) {
link(tr[next], tr[curr]);
dfs(next, curr);
}
}
int main() {
int n;
cin >> n;
vector<int> S(n), C(n);
for (int i = 0; i < n; i++) scanf("%d", &S[i]);
for (int i = 0; i < n; i++) scanf("%d", &C[i]);
for (int i = 0; i < n; i++) tr[i] = new node(S[i], C[i]);
for (int i = 0; i < n - 1; i++) {
int u, v;
scanf("%d %d", &u, &v);
u--; v--;
g[u].push_back(v);
g[v].push_back(u);
}
dfs(0, -1);
int q;
cin >> q;
for (int i = 0; i < q; i++) {
int k;
scanf("%d", &k);
if (k == 0) {
int x, y, z;
scanf("%d %d %d", &x, &y, &z);
x--; y--;
evert(tr[x]);
expose(tr[y]);
node *rch = tr[y]->rch;
tr[y]->rch = nullptr;
tr[y]->lazy = z;
push(tr[y]);
tr[y]->rch = rch;
update(tr[y]);
} else {
int x, y;
scanf("%d %d", &x, &y);
x--; y--;
evert(tr[x]);
expose(tr[y]);
node *rch = tr[y]->rch;
tr[y]->rch = nullptr;
update(tr[y]);
long long ans = sum(tr[y]);
tr[y]->rch = rch;
update(tr[y]);
printf("%lld\n", ans);
}
}
}