一直都没有判断只有一个点的情况,一直wa呀。
这道题卡得太厉害了,g++T, c++RE, 要手动扩栈。
开始用线段树来更新的,T了之后,想想只有一次查询,就用不着线段树了,直接数组标记。
#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <map>
#include <iostream>
using namespace std;
const int maxn = 1e5+5;
struct Edge
{
int v, next;
}e[maxn<<1], ee[maxn];
int g[maxn];
int idx;
void addEdge(int u, int v)
{
idx++;
e[idx].v = v;
e[idx].next = g[u];
g[u] = idx;
}
int dep[maxn], w[maxn], fa[maxn], top[maxn], son[maxn], size[maxn];
int re[maxn];
void dfs(int u)
{
son[u] = 0;
size[u] = 1;
for(int i = g[u]; i; i = e[i].next)
{
int v = e[i].v;
if(v != fa[u])
{
fa[v] = u;
dep[v] = dep[u] + 1;
dfs(v);
size[u] += size[v];
if(size[v] > size[son[u]])
son[u] = v;
}
}
}
void dfs2(int u, int tp)
{
top[u] = tp;
w[u] = ++idx;
re[idx] = u;
if(son[u])
dfs2(son[u], tp);
for(int i = g[u]; i; i = e[i].next)
{
int v = e[i].v;
if(v != fa[u] && v != son[u])
dfs2(v, v);
}
}
long long nv[maxn], ev[maxn], ans[maxn];
int main()
{
int t;
scanf("%d", &t);
for(int cas = 1; cas <= t; cas ++)
{
memset(g, 0, sizeof(g));
int n, m, u, v, k;
idx = 0;
scanf("%d%d", &n, &m);
for(int i = 1; i < n; i++)
{
scanf("%d%d", &u, &v);
ee[i].v = u;
ee[i].next = v;
addEdge(u, v);
addEdge(v, u);
}
size[0] = 0;
memset(fa, 0, sizeof(fa));
dep[1] = 1;
idx = 0;
dfs(1);
dfs2(1, 1);
char cm[10];
memset(nv, 0, sizeof(nv));
memset(ev, 0, sizeof(ev));
for(int i = 0; i < m; i++)
{
scanf("%s", cm);
scanf("%d%d%d", &u, &v, &k);
if(cm[3] == '1')
{
while(top[u] != top[v])
{
if(dep[top[u]] < dep[top[v]]) swap(u, v);
nv[w[top[u]]] += k;
nv[w[u] + 1] -= k;
u = fa[top[u]];
}
if(w[u] > w[v]) swap(u, v);
nv[w[u]] += k;
nv[w[v] + 1] -= k;
}
else{
while(top[u] != top[v])
{
if(dep[top[u]] < dep[top[v]]) swap(u, v);
ev[w[top[u]]] += k;
ev[w[u] + 1] -= k;
u = fa[top[u]];
}
if(w[u] > w[v]) swap(u, v);
ev[w[u] + 1] += k;
ev[w[v] + 1] -= k;
}
}
nv[0] = 0;
printf("Case #%d:\n", cas);
for(int i = 1; i <= n; i++)
{
nv[i] += nv[i-1];
ans[re[i]] = nv[i];
}
for(int i = 1; i < n; i++)
printf("%I64d ", ans[i]);
printf("%I64d\n", ans[n]);
ev[1] = 0;
for(int i = 2; i <= n; i++)
ev[i] += ev[i-1];
for(int i = 1; i < n; i++)
ans[i] = ev[max(w[ee[i].v], w[ee[i].next])];
if(n != 1)
{
printf("%I64d", ans[1]);
for(int i = 2; i < n; i++)
printf(" %I64d", ans[i]);
}
printf("\n");
}
return 0;
}