結果
| 問題 |
No.235 めぐるはめぐる (5)
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2016-09-30 01:26:34 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 838 ms / 10,000 ms |
| コード長 | 2,720 bytes |
| コンパイル時間 | 1,200 ms |
| コンパイル使用メモリ | 162,868 KB |
| 実行使用メモリ | 22,272 KB |
| 最終ジャッジ日時 | 2024-12-23 14:58:20 |
| 合計ジャッジ時間 | 6,009 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 3 |
コンパイルメッセージ
main.cpp: In function ‘int in()’:
main.cpp:127:14: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
127 | scanf("%d", &t);
| ~~~~~^~~~~~~~~~
ソースコード
#include <bits/stdc++.h>
using namespace std;
const long long mod = 1e9 + 7;
namespace /* lctree */ {
struct node {
node *p, *l, *r;
bool rev = false;
long long val, sum, lazy = 0, w, sw;
};
node *create_nil() {
node *x = new node();
x->l = x->r = x;
x->sw = x->sum = 0;
return x;
}
node *nil = create_nil();
node *create(int val, int w) {
node *x = new node();
x->p = x->l = x->r = nil;
x->w = x->sw = w;
x->val = val;
x->sum = x->val;
return x;
}
void fix(node *x) {
x->sum = (x->val + x->l->sum + x->r->sum) % mod;
x->sw = (x->w + x->l->sw + x->r->sw) % mod;
}
void set_rev(node *x, bool rev) {
if (x == nil) return;
if (rev == false) return;
x->rev ^= rev;
}
void set_lazy(node *x, long long lazy) {
if (x == nil) return;
(x->lazy += lazy) %= mod;
(x->sum += lazy * x->sw) %= mod;
}
void push(node *x) {
set_rev(x->l, x->rev);
set_rev(x->r, x->rev);
set_lazy(x->l, x->lazy);
set_lazy(x->r, x->lazy);
if (x->rev) swap(x->l, x->r);
(x->val += x->lazy * x->w) %= mod;
x->rev = false;
x->lazy = 0;
}
void raise(node *x) {
node *y = x->p, *z = y->p;
if (z->l == y) z->l = x;
if (z->r == y) z->r = x;
y->p = x; x->p = z;
if (y->l == x) {
y->l = x->r; x->r = y->l->p = y;
} else {
y->r = x->l; x->l = y->r->p = y;
}
fix(y);
}
bool is_root(node *x) {
return x->p->l != x && x->p->r != x;
}
void splay(node *x) {
while (!is_root(x)) {
if (!is_root(x->p)) raise((x->p->l == x) == (x->p->p->l == x->p) ? x->p : x);
raise(x);
}
}
void push_sup(node *x) {
if (x == nil) return;
push_sup(x->p);
push(x);
}
void expose(node *x) {
push_sup(x);
for (node *r = nil, *y = x; y != nil; r = y, y = y->p) {
splay(y);
y->r = r;
fix(y);
}
splay(x);
fix(x);
}
void evert(node *x) {
expose(x);
set_rev(x, true);
}
void link(node *x, node *y) {
evert(x);
expose(y);
y->r = x; x->p = y;
fix(y);
}
void cut(node *x) {
expose(x);
x->l->p = x->l = nil;
fix(x);
}
node *get_path(node *x, node *y) {
evert(x);
expose(y);
return y;
}
}
int in() {
int t;
scanf("%d", &t);
return t;
}
int main() {
int n;
cin >> n;
vector<int> S(n), C(n);
for (int i = 0; i < n; i++) S[i] = in();
for (int i = 0; i < n; i++) C[i] = in();
vector<node *> tr(n);
for (int i = 0; i < n; i++) tr[i] = create(S[i], C[i]);
for (int i = 0; i < n - 1; i++) {
int u = in() - 1, v = in() - 1;
link(tr[u], tr[v]);
}
int q = in();
while (q--) {
int t = in();
if (t == 0) {
int u = in() - 1, v = in() - 1, z = in();
set_lazy(get_path(tr[u], tr[v]), z);
} else {
int u = in() - 1, v = in() - 1;
printf("%lld\n", get_path(tr[u], tr[v])->sum);
}
}
}