感谢asm.Definer清楚明了的题解:

http://www.cnblogs.com/Asm-Definer/p/4470112.html

收获:

  1.  关于重心, 对于一个无向图, 我们这样给每条边重新确定方向: u<->v这条边将原图分成两个部分Su,Sv,w(S)表示S集合中点的权值和,那么

     u->v 当 w(Su)<w(Sv)

     u<-v 当 w(Su)>w(Sv)

     u<->v 当 w(Su)=w(Sv)

     那么从一个点沿着边的方向走,直到走到一个区域,使得走不出这个区域,那么这个区域中的任何一个点就是重心.

  2. 有了第一条,就可以运用点分来搞一些询问某个点的的东西了(这里就是询问以这个点为重心的权和).

    再用点分最多log层和类似1的性质,就可以做了.

  3. 点分不擅长求全局最...的东西,而是擅长关于某个点....的东西.

    这道题可以用是因为有重心位置的单调性.

    还有捉迷藏那道题是用堆来辅助的.

 #include <cstdio>
#include <vector>
#include <map>
#define max(a,b) ((a)>(b)?(a):(b))
#define oo 0x3f3f3f3f3f3f3f3fLL
#define N 100010
#define M N<<1
#define P 17
using namespace std; typedef long long dnt;
struct Info {
int p, s;
Info(){}
Info( int p, int s ):p(p),s(s){}
};
struct Pair {
int s, c;
Pair(){}
Pair( int s, int c ):s(s),c(c){}
}; int n, m;
int head[N], dest[M], wght[M], next[M], etot;
int idv[M], vid[N], dep[N], stu[M][P+], stp[M][P+];
int bac[N], fat[N], siz[N], vis[N], dis[N];
int bin[P+], log[M], qu[N], bg, ed;
//Info info[N][P+1]; int icnt[N];
//Pair gc[N][22]; int gcnt[N];
vector<Info> info[N];
vector<Pair> gc[N];
dnt cans[N], fans[N], sumw[N];
dnt rans[N]; int tag[N], curt; inline void uMax( int &u, int v ) { if( u<v ) u=v; }
void adde( int u, int v, int w ) {
etot++;
dest[etot] = v;
wght[etot] = w;
next[etot] = head[u];
head[u] = etot;
}
void build_lca( int s ) {
// qu fat dep dis, siz
fat[s] = ;
dep[s] = ;
dis[s] = ;
siz[s] = ;
qu[bg=ed=] = s;
while( bg<=ed ) {
int u=qu[bg++];
for( int t=head[u]; t; t=next[t] ) {
int v=dest[t], w=wght[t];
if( v==fat[u] ) continue;
fat[v] = u;
siz[v] = ;
dep[v] = dep[u]+;
dis[v] = dis[u]+w;
qu[++ed] = v;
}
}
// siz
for( register int i=ed; i>=; i-- ) {
int u=qu[i], p=fat[u];
siz[u]++;
siz[p]+=siz[u];
}
siz[s]++;
// idv vid
vid[s] = ;
idv[] = s;
for( register int i=; i<=ed; i++ ) {
int u=qu[i];
int cur=vid[u]+;
for( register int t=head[u]; t; t=next[t] ) {
int v=dest[t];
if( v==fat[u] ) continue;
idv[cur] = u;
cur++;
vid[v] = cur;
idv[cur] = v;
cur += siz[v]+siz[v]-;
}
}
idv[n+n] = s;
// bin log
int idc = n+n;
bin[] = ;
for( int i=; i<=P; i++ ) bin[i] = bin[i-]<<;
log[] = -;
for( int i=; i<=idc; i++ ) log[i] = log[i>>]+;
// stu stp
for( int i=; i<=idc; i++ ) {
stu[i][] = idv[i];
stp[i][] = dep[idv[i]];
}
for( int p=; p<=log[idc]; p++ ) {
for( register int i=; i<=idc-bin[p]+; i++ ) {
if( stp[i][p-] < stp[i+bin[p-]][p-] ) {
stp[i][p] = stp[i][p-];
stu[i][p] = stu[i][p-];
} else {
stp[i][p] = stp[i+bin[p-]][p-];
stu[i][p] = stu[i+bin[p-]][p-];
}
}
}
}
inline int lca( int u, int v ) {
int lf=vid[u], rg=vid[v];
if( lf>rg ) swap(lf,rg);
int p = log[rg-lf+];
if( stp[lf][p] < stp[rg-bin[p]+][p] )
return stu[lf][p];
else
return stu[rg-bin[p]+][p];
}
inline int qu_dis( int u, int v ) {
int ca = lca(u,v);
return dis[u]+dis[v]-(dis[ca]<<);
}
int build_vdcp( int s ) {
int c;
// qu fat, siz bac
fat[s] = ;
siz[s] = bac[s] = ;
qu[bg=ed=] = s;
while( bg<=ed ) {
int u=qu[bg++];
for( int t=head[u]; t; t=next[t] ) {
int v=dest[t];
if( v==fat[u] || vis[v] ) continue;
fat[v] = u;
siz[v] = bac[v] = ;
qu[++ed] = v;
}
}
// siz bac
for( register int i=ed; i>=; i-- ) {
int u=qu[i], p=fat[u];
siz[u]++;
siz[p]+=siz[u];
uMax( bac[p], siz[u] );
}
siz[s]++;
// bac c
c = ;
for( register int i=; i<=ed; i++ ) {
int u=qu[i];
uMax( bac[u], siz[s]-siz[u] );
if( bac[u]<bac[c] ) c=u;
}
// qu info
vis[c] = true;
vector<int> stk;
for( int t=head[c]; t; t=next[t] ) {
int s=dest[t], cc;
if( vis[s] ) continue; qu[bg=ed=] = s;
fat[s] = c;
stk.clear();
while( bg<=ed ) {
int u=qu[bg++];
stk.push_back( u );
for( int t=head[u]; t; t=next[t] ) {
int v=dest[t];
if( v==fat[u] || vis[v] ) continue;
qu[++ed] = v;
fat[v] = u;
}
}
cc = build_vdcp(s);
gc[c].push_back(Pair(s,cc));
// gc[c][gcnt[c]] = Pair(s,cc);
// gcnt[c]++;
for( register int t=stk.size()-; t>=; t-- ) {
int u=stk[t];
info[u].push_back( Info(c,cc) );
// info[u][icnt[u]] = Info(c,cc);
// icnt[u]++;
}
}
return c;
}
dnt query( int u ) {
if( tag[u]==curt ) return rans[u];
tag[u] = curt;
dnt rt = cans[u];
for( int t=; t<info[u].size(); t++ ) {
// for( int t=icnt[u]-1; t>=0; t-- ) {
int p=info[u][t].p, s=info[u][t].s;
rt += cans[p]-fans[s]+(sumw[p]-sumw[s])*qu_dis(u,p);
}
return rans[u]=rt;
}
dnt search( int u ) {
dnt su = query(u);
for( int t=; t<gc[u].size(); t++ ) {
// for( int t=gcnt[u]-1; t>=0; t-- ) {
Pair &p = gc[u][t];
dnt a=query(p.s);
if( a<su ) return search(p.c);
}
return su;
}
void modify( int u, int delta ) {
sumw[u] += delta;
for( int t=info[u].size()-; t>=; t-- ) {
// for( int t=icnt[u]-1; t>=0; t-- ) {
int p=info[u][t].p, s=info[u][t].s;
dnt d = (dnt)delta*qu_dis(u,p);
cans[p] += d;
fans[s] += d;
sumw[p] += delta;
}
}
int main() {
scanf( "%d%d", &n, &m );
for( int i=,u,v,w; i<n; i++ ) {
scanf( "%d%d%d", &u, &v, &w );
adde( u, v, w );
adde( v, u, w );
}
bac[] = n;
int core = build_vdcp();
build_lca();
for( int t=,u,d; t<=m; t++ ) {
scanf( "%d%d", &u, &d );
modify( u, d );
curt = t;
printf( "%lld\n", search(core) );
}
}

bzoj 3924 点分的更多相关文章

  1. [BZOJ 4332] [JSOI2012]分零食(DP+FFT)

    [BZOJ 4332] [JSOI2012]分零食(DP+FFT) 题面 同学们依次排成了一列,其中有A位小朋友,有三个共同的欢乐系数O,S和U.如果有一位小朋友得到了x个糖果,那么她的欢乐程度就是\ ...

  2. BZOJ 3924 / Luogu P3345 [ZJOI2015]幻想乡战略游戏 (动态点分治/点分树)

    题意 树的结构不变,每个点有点权,每一条边有边权,有修改点权的操作,设xxx为树中一点.求∑idist(x,i)∗a[i]\sum_idist(x,i)*a[i]i∑​dist(x,i)∗a[i]的最 ...

  3. bzoj 3924 [Zjoi2015]幻想乡战略游戏——动态点分治(暴力移动找重心)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3924 度数只有20,所以从一个点暴力枚举其出边,就能知道往哪个方向走. 知道方向之后直接走到 ...

  4. BZOJ 4710: [Jsoi2011]分特产 [容斥原理]

    4710: [Jsoi2011]分特产 题意:m种物品分给n个同学,每个同学至少有一个物品,求方案数 对于每种物品是独立的,就是分成n组可以为空,然后可以用乘法原理合起来 容斥容斥 \[ 每个同学至少 ...

  5. bzoj 3924: [Zjoi2015]幻想乡战略游戏

    Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来, ...

  6. ●BZOJ 4710 [Jsoi2011]分特产

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4710 题解: 容斥,组合先看看这个方案数的计算:把 M 个相同的东西分给 N 个人,每个人可 ...

  7. bzoj 4710: [Jsoi2011]分特产

    Description JYY 带队参加了若干场ACM/ICPC 比赛,带回了许多土特产,要分给实验室的同学们. JYY 想知道,把这些特产分给N 个同学,一共有多少种不同的分法?当然,JYY 不希望 ...

  8. 【BZOJ 3924】[Zjoi2015]幻想乡战略游戏

    题目: 题解: 对点分树理解加深了233,膜拜zzh干翻紫荆花. 感谢zzh的讲解. 首先优化基于传统DP,假设树不发生变化,我们就可以利用DP求出带权重心. 考虑修改,我们思路不变,还是从root开 ...

  9. bzoj 4332: JSOI2012 分零食 快速傅立叶变换

    题目: Description 同学们依次排成了一列,其中有A位小朋友,有三个共同的欢乐系数O,S和U.如果有一位小朋友得到了x个糖果,那么她的欢乐程度就是\(f(x)=O*x^2+S*x+U\) 现 ...

随机推荐

  1. headers 替换脚本

    python代码 headers = """ Accept: */* Accept-Encoding: gzip, deflate, br Accept-Language ...

  2. 整理一下odoo10在windows系统下部署的流程

    odoo10环境搭建 所需依赖: Python3.5 odoo10.0 Node.js PostgreSQL 9.5 PyCharm 专业版 1.首先先安装好Python3.5,并设置好环境变量 2. ...

  3. 026_关于shell中的特殊变量$0 $n $* $@ $! $?

    一. $n:获取当前执行的shell脚本的第N个参数,n=1..9,当n为0时表示脚本的文件名,如果n大于9,用大括号括起来like${10}. $*:获取当前shell的所有参数,将所有的命令行参数 ...

  4. 004_i686和x86_64的区别

    找回TCL隐藏分区(转载) 用Wubi安装 Ubuntu 出现(Initranfs)问题的解决方案 i686和x86_64的区别 2009-04-11 08:19:31|  分类: 电脑问题 |  标 ...

  5. 图解 Paxos 一致性协议

    转自:http://blog.jobbole.com/106327/ 前言 Paxos 一致性协议可以说是一致性协议研究的起点,也以难以理解闻名.其实协议本身并没有多难理解,它的难理解性主要体现在:为 ...

  6. Oracle 数据库逻辑结构

    注:本文来源于 <腾科OCP培训课堂>.非准许商业活动. Oracle 数据库逻辑结构 一.存储关系 Oracle 数据库逻辑上是由一个或多个表空间组成的,表空间物理上是由一个或多个数据 ...

  7. 【linux】centos6.9安装gearman

    1.确认yum源没问题,如果有问题,参照这里更换 2. yum install -y boost-devel gperf libevent-devel libuuid-devel yum instal ...

  8. python----多继承C3算法

    https://blog.csdn.net/fmblzf/article/details/52512145

  9. poj2992 阶乘分解

    /* 将C(n,k)质因数分解,然后约束个数按公式计算 */ #include<iostream> #include<cstring> #include<cstdio&g ...

  10. python 全栈开发,Day32(知识回顾,网络编程基础)

    一.知识回顾 正则模块 正则表达式 元字符 : . 匹配除了回车以外的所有字符 \w 数字字母下划线 \d 数字 \n \s \t 回车 空格 和 tab ^ 必须出现在一个正则表达式的最开始,匹配开 ...