ZJOI2015 幻想乡战略游戏 动态点分治_树链剖分_未调完
最近写动态点分治快自闭了QAQ.......
有时间再来写一下题解.
其实我不会告诉你我还没调出来呢QAQ
Code:
// luogu-judger-enable-o2
// luogu-judger-enable-o2
#include <bits/stdc++.h>
#define setIO(s) freopen(s".in","r",stdin) // ,freopen(s".out","w",stdout)
#define maxn 300000
#define N 300010
#define ll long long
#define inf 0x7f7f7f
using namespace std;
int n,m,cnt,sn,root;
int hd[N],to[N],nx[N],val[N];
void add(int u,int v,int c)
{
nx[++cnt] = hd[u],hd[u] = cnt,to[cnt] = v,val[cnt] = c;
}
namespace heavyedge
{
int fa[N],hson[N],siz[N],top[N],dep[N];
ll dis[N];
void dfs1(int u,int ff)
{
fa[u] = ff;
for(int i = hd[u]; i ; i = nx[i])
{
if(to[i] == ff) continue;
dep[to[i]] = dep[u] + 1,dis[to[i]] = dis[u] + val[i];
dfs1(to[i],u);
siz[u] += siz[to[i]];
if(siz[to[i]] > siz[hson[u]]) hson[u] = to[i];
}
}
void dfs2(int u,int tp)
{
top[u] = tp;
if(hson[u]) dfs2(hson[u],tp);
for(int i = hd[u]; i ; i = nx[i])
{
if(to[i] == hson[u] || to[i] == fa[u]) continue;
dfs2(to[i],to[i]);
}
}
int LCA(int a,int b)
{
while(top[a] != top[b]) dep[top[a]] < dep[top[b]] ? b = fa[top[b]]: a = fa[top[a]];
return dep[a] < dep[b] ? a : b;
}
int main()
{
dfs1(1,0),dfs2(1,1);
return 0;
}
};
ll Dis(int a,int b)
{
return heavyedge::dis[a] + heavyedge::dis[b] - (heavyedge::dis[heavyedge::LCA(a,b)] << 1);
}
int siz[N],vis[N],Fa[N],hto[N],f[N],tmp;
ll sumv[N],sumd[N];
void GetRoot(int u,int ff)
{
siz[u] = 1,f[u] = 0;
for(int i = hd[u]; i ; i = nx[i])
{
if(vis[to[i]] || to[i] == ff) continue;
GetRoot(to[i],u);
siz[u] += siz[to[i]];
f[u] = max(f[u],siz[to[i]]);
}
f[u] = max(f[u],sn - siz[u]);
if(f[root] > f[u]) root = u;
}
void dfs(int u)
{
vis[u] = 1;
for(int i = hd[u]; i ; i = nx[i])
{
if(vis[to[i]]) continue;
root = 0, sn = siz[to[i]], GetRoot(to[i],u), hto[i] = root,Fa[root] = u, dfs(root);
}
}
#define fax(i) (i + n)
void Update(int x,int w)
{
sumv[x] += w;
for(int i = x; Fa[i]; i = Fa[i])
{
ll dis = Dis(x, Fa[i]);
sumv[Fa[i]] += w;
sumd[Fa[i]] += 1ll*dis * w;
sumd[fax(i)] += 1ll*dis * w;
}
}
ll calc(int x)
{
ll res = sumd[x];
for(int i = x; Fa[i]; i = Fa[i])
{
ll dis = Dis(x, Fa[i]);
res += 1ll*(sumv[Fa[i]] - sumv[i]) * dis;
res += sumd[Fa[i]] - sumd[fax(i)];
}
return res;
}
ll Query(int u)
{
ll tmp = calc(u);
for(int i = hd[u]; i ; i = nx[i])
{
if(calc(to[i]) < tmp) return Query(to[i]);
}
return tmp;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i = 1,a,b,c;i < n; ++i) scanf("%d%d%d",&a,&b,&c),add(a,b,c),add(b,a,c);
heavyedge :: main();
f[0] = inf, sn = n, root = 0, GetRoot(1,0),tmp = root,dfs(root), root = tmp;
int u,e;
while(m--)
{
scanf("%d%d",&u,&e),Update(u,e),printf("%lld\n",Query(root));
}
return 0;
}