[ZJOI2015][bzoj3924] 幻想乡战略游戏 [动态点分治]
唉:-(动态点分治的思想真是复杂......
先码住,再做几道题再来填坑
PS:接下来的Code因为用了倍增lca所以TLE一部分,但是懒得改成RMQ了......
Code:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
inline int read(){
int re=,flag=;char ch=getchar();
while(ch>''||ch<''){
if(ch=='-') flag=-;
ch=getchar();
}
while(ch>=''&&ch<='') re=(re<<)+(re<<)+ch-'',ch=getchar();
return re*flag;
}
int n,m,cnt,sum,root,first[],fa[],siz[],son[];
bool vis[]={};
ll dis1[],dis2[],tot[];
struct edge{
int to,next,w;
}a[];
void add(int u,int v,int w){
a[++cnt]=(edge){v,first[u],w};first[u]=cnt;
a[++cnt]=(edge){u,first[v],w};first[v]=cnt;
}
inline int _max(int l,int r){return (l>r)?l:r;}
inline int _min(int l,int r){return (l<r)?l:r;}
inline void _swap(int &l,int &r){l^=r;r^=l;l^=r;}
struct Original_Tree{
int cnt,First[],dis[],dep[];
int st[][];
struct Edge{int to,next,w;}A[];
void add(int u,int v,int w){
A[++cnt]=(Edge){v,First[u],w};First[u]=cnt;
A[++cnt]=(Edge){u,First[v],w};First[v]=cnt;
}
void ddfs(int u,int f){
st[u][]=f;int i,v;
//cout<<"dfs "<<u<<" "<<f<<" "<<dis[u]<<" "<<dep[u]<<"\n";
for(i=First[u];~i;i=A[i].next){
v=A[i].to;
if(v==f) continue;
dis[v]=dis[u]+A[i].w;dep[v]=dep[u]+;
ddfs(v,u);
}
}
void initst(){
dis[]=;dep[]=;ddfs(,);int i,j;
for(j=;j<;j++){
for(i=;i<=n;i++) st[i][j]=st[st[i][j-]][j-];
}
//for(i=1;i<=n;i++){
//for(j=0;j<=3;j++) cout<<st[i][j]<<" ";
//cout<<"\n";
//}
}
int getdis(int u,int v){
if(dep[u]>dep[v]) _swap(u,v);
int i,lca,tu=u,tv=v;
//cout<<"begin "<<u<<" "<<v<<"\n";
for(i=;i>=;i--)
if(dep[st[v][i]]>=dep[u]) v=st[v][i];
//cout<<"half finish "<<u<<" "<<v<<"\n";
if(u==v) return dis[tv]-dis[u];
for(i=;i>=;i--)
if(st[u][i]!=st[v][i]){
u=st[u][i];
v=st[v][i];
}
lca=st[u][];
//cout<<"getdis "<<tu<<" "<<tv<<" "<<lca<<"\n";
return dis[tu]+dis[tv]-*dis[lca];
}
}T;
void getroot(int u,int f){
int i,v;siz[u]=;son[u]=;
for(i=T.First[u];~i;i=T.A[i].next){
v=T.A[i].to;
if(v==f||vis[v]) continue;
getroot(v,u);
siz[u]+=siz[v];son[u]=_max(son[u],siz[v]);
}
son[u]=_max(son[u],sum-siz[u]);
if(son[u]<son[root]) root=u;
}
void dfs(int u,int f){
int i,v;vis[u]=;fa[u]=f;
for(i=T.First[u];~i;i=T.A[i].next){
v=T.A[i].to;
if(vis[v]) continue;
sum=siz[v];root=;
getroot(v,);add(u,root,v);
dfs(root,u);
}
}
void change(int u,int delta){
tot[u]+=delta;int v,dis;
for(v=u;fa[v];v=fa[v]){
dis=T.getdis(u,fa[v]);
dis1[fa[v]]+=(ll)dis*delta;
dis2[v]+=(ll)dis*delta;
tot[fa[v]]+=delta;
}
}
ll calc(int u){
ll re=dis1[u];int i,dis;
for(i=u;fa[i];i=fa[i]){
dis=T.getdis(u,fa[i]);
re+=dis1[fa[i]]-dis2[i];
re+=dis*(tot[fa[i]]-tot[i]);
}
return re;
}
ll query(int u){
ll re=calc(u),tmp;int i,v;
for(i=first[u];~i;i=a[i].next){
v=a[i].to;
tmp=calc(a[i].w);
if(tmp<re) return query(v);
}
return re;
}
int main(){
freopen("zjoi15_tree4.in","r",stdin);
freopen("zjoi15_tree.out","w",stdout); memset(tot,,sizeof(tot));
memset(dis1,,sizeof(dis1));
memset(dis2,,sizeof(dis2));
memset(first,-,sizeof(first));
memset(T.First,-,sizeof(T.First));
int i,t1,t2,t3,tmp;
n=read();m=read();
for(i=;i<n;i++){
t1=read();t2=read();t3=read();
T.add(t1,t2,t3);
}
T.initst();
sum=son[]=n;root=;
getroot(,);tmp=root;
dfs(root,);root=tmp;
for(i=;i<=m;i++){
t1=read();t2=read();
change(t1,t2);
printf("%lld\n",query(root));
}
}
[ZJOI2015][bzoj3924] 幻想乡战略游戏 [动态点分治]的更多相关文章
- loj 2135 「ZJOI2015」幻想乡战略游戏 - 动态点分治
题目传送门 传送门 题目大意 给定一棵树,初始点权都为0,要求支持: 修改点权 询问带权重心 询问带权重心就在点分树上跑一下就行了.(枚举跳哪个子树更优) 剩下都是基础点分治. 学了一下11-dime ...
- 【BZOJ3924】[Zjoi2015]幻想乡战略游戏 动态树分治
[BZOJ3924][Zjoi2015]幻想乡战略游戏 Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网 ...
- [ZJOI2015]幻想乡战略游戏——动态点分治
[ZJOI2015]幻想乡战略游戏 带修改下,边点都带权的重心 随着变动的过程中,一些子树内的点经过会经过一些公共边.考虑能不能对这样的子树一起统计. 把树上贡献分块. 考虑点分治算法 不妨先把题目简 ...
- [BZOJ3924][ZJOI2015]幻想乡战略游戏(动态点分治)
题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来,更别说和别人打 ...
- 【bzoj3924】[Zjoi2015]幻想乡战略游戏 动态点分治
题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来,更别说和别人打 ...
- P3345 [ZJOI2015]幻想乡战略游戏 动态点分治
\(\color{#0066ff}{ 题目描述 }\) 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越 ...
- ZJOI2015 幻想乡战略游戏 动态点分治_树链剖分_未调完
Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来, ...
- BZOJ 3924: [Zjoi2015]幻想乡战略游戏(动态点分治)
这种动态点分治嘛,GDKOI时听打到了,也有同学讲到了,所以印象比较深刻也就想出来了,然后就在实现方面卡了好久= = 不得不说CLJ说得真的太简单了,实现方面根本没提. 首先我们可以先用树分治构建出这 ...
- 洛谷P3345 [ZJOI2015]幻想乡战略游戏 [动态点分治]
传送门 调了两个小时,终于过了-- 凭啥人家代码80行我180行啊!!! 谁叫你大括号换行 谁叫你写缺省源 思路 显然,补给点所在的位置就是这棵树的带权重心. 考虑size已知时如何找重心:一开始设答 ...
随机推荐
- python __getattr__ __setattr__
class Rectangle: def __init__(self): self.width = 0 self.height = 0 def __setattr__(self, key, value ...
- CSS之常见文字样式整理
常见文字样式 行高:line-height,当我i们将行高的大小设置成当前元素的高度时,可以实现当行文本在当前元素中垂直方向居中显示的效果 水平对齐方式:text-align:left|center| ...
- java编程基础——栈压入和弹出序列
题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压 ...
- python之列表推导、迭代器、生成器
http://blog.chinaunix.net/uid-26722078-id-3484197.html 1.列表推导 看几个例子,一切就明白了. #!/usr/bin/python number ...
- python-kafka源码解析之socketpair
socket基本操作包括:socket()函数创建socket文件描述符,唯一标识一个socket.bind()函数,将ip:port和socket绑定listen()函数来监听这个socket,假如 ...
- Vue之Vue-touch的使用
最近项目中,有的页面发现设置返回键看起来怪怪的,感觉与整体不协调,于是就考虑使用手势滑动事件来实现返回功能~ 开叉查阅资料~找到了vue-touch,使用起来可谓是简单粗暴啊,适合我这样的快速开发人员 ...
- ElasticSearch High Level REST API【2】搜索查询
如下为一段带有分页的简单搜索查询示例 在search搜索中大部分的搜索条件添加都可通过设置SearchSourceBuilder来实现,然后将SearchSourceBuilder RestHighL ...
- String&StringBuffer&StringBuilder区别
String String类是final类故不可以继承,也就意味着String引用的字符串内容是不能被修改.String有两种实例化方式: (1)直接赋值(例中,String str = &q ...
- Node.js 特点
1.单线程 在Java.PHP或者.net等服务器端语言中,会为每一个客户端连接创建一个新的线程.而每个线程需要耗费大约2MB内存.也就是说,理论上,一个8GB内存的服务器可以同时连接的最大用户数 ...
- linux 的安装
3linux 软件安装 3.1 vm ware 软件安装 双击VMware-workstation-full-10.0.2-1744117.1398244508.exe 单击下一步 单击下一步 选择典 ...