【题目大意】

    给定一棵树,边有边权,每个节点有一些兵,现在叶子节点在0时刻被占领,并且任意节点在x被占领,那么从x+1开始,每单位时间产生一个兵,兵会顺着父亲节点一直走到根(1),其中每经过一个节点,该节点的兵储量减少1,问所有节点都被攻陷的最晚时间。

  【数据范围】

    n<=10^5.

  首先我们可以设每个节点被攻占的时间为w[i],那么对于一个父节点x,我们可以二分一个答案,来判断这个答案是否合法,那么假设我们分到的值为time,那么对于x子树中所有的节点p,每个节点的贡献为max(0,time-w[p]-d[x][p])。那么我们只需要判断贡献和与x节点的兵的数量就可以了。

  那么对于一个点,我们可以用一颗平衡树来存这个点为根节点的子树中所有节点的w[p]+d[x][p]值,那么对于一个二分到的答案,我们只需要判断树中小于time的和,再用time*size减去就好了。对于一个节点,我们只需要启发式合并他所有的子节点的平衡树就好了。

  反思:开始写的时候没看long long,结果发现连第二个测试点都过不去,然后开了之后就出了各种各样的问题,开始是return 0没有改成return 1LL,后来发现平衡树中维护的sum值有的时候没有被更新,我是在插入和删除的时候修改的这个,和size一起修改,也不知道哪儿错了,后来就直接在询问的时候维护sum,然后还是不行,后来能加上的地方都加上了才过了。。。。

  

//By BLADEVIL
#include <cstdio>
#include <algorithm>
#define maxn 100010
#define LL long long using namespace std; LL n,l,tot,save;
LL a[maxn],pre[maxn<<],other[maxn<<],last[maxn],len[maxn<<];
LL w[maxn],flag[maxn],que[maxn],dis[maxn],rot[maxn];
LL left[maxn<<],right[maxn<<],key[maxn<<],size[maxn<<],sum[maxn<<]; void connect(LL x,LL y,LL z) {
pre[++l]=last[x];
last[x]=l;
other[l]=y;
len[l]=z;
} void left_rotate(LL &t) {
LL k=right[t];
right[t]=left[k];
left[k]=t;
size[k]=size[t];
sum[k]=sum[t];
size[t]=size[left[t]]+size[right[t]]+1LL;
sum[t]=sum[left[t]]+sum[right[t]]+key[t];
t=k;
} void right_rotate(LL &t) {
LL k=left[t];
left[t]=right[k];
right[k]=t;
size[k]=size[t];
sum[k]=sum[t];
size[t]=size[left[t]]+size[right[t]]+1LL;
sum[t]=sum[left[t]]+sum[right[t]]+key[t];
t=k;
} void maintain(LL &t,int flag) {
if (!flag) {
if (size[left[left[t]]]>size[right[t]])
right_rotate(t); else
if (size[right[left[t]]]>size[right[t]])
left_rotate(left[t]),right_rotate(t); else return ;
} else {
if (size[right[right[t]]]>size[left[t]])
left_rotate(t); else
if (size[left[right[t]]]>size[left[t]])
right_rotate(right[t]),left_rotate(t); else return ;
}
maintain(left[t],); maintain(right[t],);
maintain(t,); maintain(t,);
//sum[t]=sum[left[t]]+sum[right[t]]+key[t];
} void t_insert(LL &t,LL v) {
if (!t) {
t=++tot;
left[t]=right[t]=0LL;
size[t]=1LL;
key[t]=sum[t]=v;
} else {
size[t]++; sum[t]+=v;
if (v<key[t]) t_insert(left[t],v); else t_insert(right[t],v);
maintain(t,v>=key[t]);
}
}
/*
LL t_delete(LL &t,LL v) {
size[t]--;
if ((v==key[t])||((v>key[t])&&(!right[t]))||((v<key[t])&&(!left[t]))) {
save=key[t];
if ((!left[t])||(!right[t]))
t=left[t]+right[t]; else key[t]=t_delete(left[t],v+1LL);
} else {
if (v<key[t]) return t_delete(left[t],v); else return t_delete(right[t],v);
}
sum[t]=sum[left[t]]+sum[right[t]]+key[t];
return save;
}
*/ LL t_delete(LL &t,LL v) {
if ((v==key[t])||((v>key[t])&&(!right[t]))||((v<key[t])&&(!left[t]))) {
save=key[t];
if ((!left[t])||(!right[t])) {
t=left[t]+right[t];
sum[t]=sum[left[t]]+sum[right[t]]+key[t];
}else key[t]=t_delete(left[t],v+1LL);
//tmp = key[t];
} else {
if (v<key[t]) save = t_delete(left[t],v); else save = t_delete(right[t],v);
}
//size[t]=size[left[t]]+size[right[t]]+1;
sum[t]=sum[left[t]]+sum[right[t]]+key[t];
return save;
} void combine(LL &t1,LL &flag1,LL t2,LL flag2) {
if (size[t1]<size[t2]) swap(t1,t2),swap(flag1,flag2);
while (t2) {
t_insert(t1,key[t2]+flag2-flag1);
t_delete(t2,key[t2]);
}
} LL judge(LL t,LL time){
sum[t]=sum[left[t]]+sum[right[t]]+key[t];
if (!t) return 0LL;
if (key[t]<=time)
return judge(right[t],time)+(size[left[t]]+1LL)*time-sum[left[t]]-key[t]; else
return judge(left[t],time);
} void work() {
LL h=0LL,t=1LL;
que[]=1LL; dis[]=1LL;
while (h<t) {
LL cur=que[++h];
for (LL p=last[cur];p;p=pre[p]) {
if (dis[other[p]]) continue;
que[++t]=other[p];
dis[other[p]]=dis[cur]+1LL;
}
}
//for (LL i=1;i<=n;i++) printf("%d ",que[i]); printf("\n");
for (LL i=n;i;i--) {
LL cur=que[i];
for (LL p=last[cur];p;p=pre[p]) {
if (dis[other[p]]<dis[cur]) continue;
combine(rot[cur],flag[cur],rot[other[p]],flag[other[p]]+len[p]);
}
if ((!rot[cur])||(!a[cur])) {
t_insert(rot[cur],-flag[cur]);
//printf("%lld %lld %lld\n",cur,rot[cur],flag[cur]);
//for (LL i=1;i<=20;i++) printf("%lld %lld %lld %lld %lld %lld\n",i,left[i],right[i],size[i],key[i],sum[i]);
continue;
}
//printf("%lld %lld %lld\n",cur,rot[cur],flag[cur]);
//for (LL i=1;i<=20;i++) printf("%lld %lld %lld %lld %lld %lld\n",i,left[i],right[i],size[i],key[i],sum[i]);
LL l=1LL,r=1LL<<,mid,ans;
while (l<=r) {
//printf("%d %d\n",l,r);
mid=l+r>>1LL;
//if (cur==1) printf("%lld %lld\n",l,r);
if (judge(rot[cur],mid-flag[cur])>=a[cur]) r=mid-1LL,ans=mid; else l=mid+1LL;
}
w[cur]=ans;
//if (cur==1) printf("|%lld\n",judge(rot[cur],-6));
t_insert(rot[cur],w[cur]-flag[cur]);
//printf("%lld %lld %lld\n",cur,rot[cur],flag[cur]);
//for (LL i=1;i<=20;i++) printf("%lld %lld %lld %lld %lld %lld\n",i,left[i],right[i],size[i],key[i],sum[i]);
}
//printf("%lld %lld\n",rot[1],flag[1]);
//for (LL i=1;i<=20;i++) printf("%lld %lld %lld %lld %lld %lld\n",i,left[i],right[i],size[i],key[i],sum[i]);
//for (LL i=1;i<=n;i++) printf("%lld ",w[i]); printf("\n");
LL ans=0LL;
for (int i=;i<=n;i++) ans=max(ans,w[i]);
printf("%lld\n",ans);
} void check() {
LL t1=,t2=,flag1=,flag2=;
for (LL i=;i<=;i++) t_insert(t1,i),t_insert(t2,i); t_insert(t2,);
combine(t1,flag1,t2,flag2);
printf("%lld\n",t1);
for (LL i=;i<=;i++) printf("%ld %lld %lld %lld %lld %lld\n",i,left[i],right[i],size[i],key[i],sum[i]);
return ;
LL t=;
for (LL i=;i<=;i++) t_insert(t,i);
t_delete(t,); printf("%lld\n",t);
for (LL i=;i<=;i++) printf("%lld %lld %lld %lld %lld %lld\n",i,left[i],right[i],size[i],key[i],sum[i]);
printf("%lld\n",judge(t,));
} int main() {
//check(); return 0;
freopen("conquer.in","r",stdin); freopen("conquer.out","w",stdout);
scanf("%lld",&n);
for (LL i=;i<=n;i++) scanf("%lld",&a[i]);
for (LL i=;i<n;i++) {
LL x,y,z; scanf("%lld%lld%lld",&x,&y,&z);
connect(x,y,z); connect(y,x,z);
}
work();
fclose(stdin); fclose(stdout);
return ;
}

【HNOI】 攻城略池 tree-dp的更多相关文章

  1. YbtOJ#763-攻城略池【线段树合并】

    正题 题目链接:http://www.ybtoj.com.cn/problem/763 题目大意 给出\(n\)个点的一棵树,每个\(d_i=0\)的点每秒会产生一个士兵往根节点走,走到一个节点让一个 ...

  2. 软件攻城狮究级装B指南

    引言 装B于无形,随性而动,顺道而行,待霸业功成之时,你会发现:装B是牛B最好的的试金石. -- SuperDo 第一章.人间兵器(准备工具) <论语·魏灵公>:“工欲善其事,必先利其器. ...

  3. 2015Web前端攻城之路

    2015目标成为一名合格的前端攻城狮. 养成计划: 1.html / css 2.js 3.ajax 4.框架 5.项目实战

  4. 安全攻城狮研发技能栈V1.0,附详细点评~

    2015-12-21 正宗好PT 正宗好PT 今天公司年会,又木有抽到奖,求安慰/(ㄒoㄒ)/~~ 言归正传,我曾经在推特发过一个Skill CheatSheet,被转发和点赞了几百次,我又更新了一下 ...

  5. Android优秀资源整理合集(论菜鸟到高级攻城狮)

    转载请注明转自:http://blog.csdn.net/u011176685/article/details/51434702 csdn文章:Android优秀资源整理合集(论菜鸟到高级攻城狮) 时 ...

  6. JBPM4之decision节点:3、程序猿|菜鸟|攻城狮|牛人

    JBPM入门系列文章: JBPM4入门——1.jbpm简要介绍 JBPM4入门——2.在eclipse中安装绘制jbpm流程图的插件 JBPM4入门——3.JBPM4开发环境的搭建 JBPM4入门—— ...

  7. 攻城狮送女友的CSS3生日蛋糕

    在线预览:http://keleyi.com/keleyi/phtml/html5/29.htm 代码如下: <!DOCTYPE html> <html> <head&g ...

  8. 遗留系统:IT攻城狮永远的痛

    我常常觉得我们非常幸运,我们现在所处的时代是一个令人振奋的时代,我们进入了软件工业时代.在这个时代里,我们进行软件开发已经不再是一个一个的小作坊,我们在进行着集团化的大规模开发.我们开发的软件不再是为 ...

  9. 96. Unique Binary Search Trees (Tree; DP)

    Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For examp ...

随机推荐

  1. python爬虫 妹子图片网

    代码如下 #coding=utf-8 import os import re import urllib from time import sleep import requests from lxm ...

  2. Vim新手节省时间的10多个小技巧

    Vim新手节省时间的10多个小技巧 Vim 是很多开发者的首选编辑器,通过设置正确的命令和快捷方式,它可以帮你更快的完成工作.这篇文章我们为 Vim 新手提供一些快捷键等方面的小技巧,帮你提升工作效率 ...

  3. Filezilla 绿色版 禁止升级 能用。

    FileZilla还是挺好用的,但是如果钟情于 绿色版的话,肯定首选是 免安装绿色版.但是呢,能找到的所谓的免升级 绿色版,都不能用.只要是打开软件了,就会在你还没有设置更新之前,就已经升级号了.并且 ...

  4. CSS设计指南之一 HTML标记与文档结构

    HTML标记与文档结构 之所以从HTML讲起,是因为CSS的用途就是为HTML标记添加样式. 1.1 HTML标记基础 对于每个包含内容的元素,根据它所包含的内容是不是文本,有两种不同的方式给它们加标 ...

  5. leetcode 整理

    1.Two Sum 构造Comparator,KSum 这一类的问题最基本的一题, 解法: 先sort,然后双指针,头尾各一个.进行加逼找值. 对于其余的KSum最终是降次到2次. 如3Sum固定一个 ...

  6. 查询MySQL某字段相同值得重复数据

    1.先查询重复的id: SELECT book_id,COUNT(*) AS COUNT FROM xs_book_source WHERE site_id=5 GROUP BY book_id HA ...

  7. 动态include是通过servlet进行页面信息交互的

    动态include是通过servlet进行页面信息交互的

  8. (转)python 搭建libsvm方法。python版本和libsvm版本匹配很重要!

    <集体智慧编程>关于婚介数据集的SVM分类 转自:http://muilpin.blog.163.com/blog/static/165382936201131875249123/   作 ...

  9. 【题解】CF#1012 C-Hill

    感觉这题的状态还是比较明显的.设置状态 \(f[i][j][0/1]\) 表示dp到第 \(i\) 个位置,前面(包括这里)已经出现了 \(j\) 个山峰,当前位置是不是山峰即可 dp.这样的状态有一 ...

  10. BZOJ1854:[SCOI2010]连续攻击游戏——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=1854 https://www.luogu.org/problemnew/show/P1640 lxh ...