LOJ#3036. 「JOISC 2019 Day3」指定城市

一个点的可以dp出来

两个点也可以dp出来

后面的就是在两个点的情况下选一条最长的链加进去,用线段树维护即可

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 200005
#define ba 47
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 +c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
struct node {
int to,next;int64 val;
}E[MAXN * 2];
int head[MAXN],sumE,N;
int64 ans[MAXN],all;
void add(int u,int v,int c) {
E[++sumE].to = v;
E[sumE].next = head[u];
E[sumE].val = c;
head[u] = sumE;
} namespace one {
int64 dis[2][MAXN],fir;
void dfs(int u,int fa) {
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v == fa) {dis[1][u] = dis[1][fa] + E[i].val;fir += E[i].val;}
else dis[0][v] = dis[0][u] + E[i].val;
}
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v != fa) dfs(v,u);
}
}
void Main() {
dfs(1,0);
int64 res = fir;
for(int i = 2 ; i <= N ; ++i) {
res = max(res,fir + dis[0][i] - dis[1][i]);
}
ans[1] = all - res;
}
}
namespace two {
int64 dis[2][MAXN],fir,mval = 0;
pair<int64,int> dp[MAXN];
int siz[MAXN],dfn[MAXN],idx,line[MAXN],fa[MAXN],S = 1,T = 1;
bool vis[MAXN];
struct node {
int l,r,pos;int64 mv,lz;
}tr[MAXN * 4];
void dfs(int u) {
siz[u] = 1;dfn[u] = ++idx;line[idx] = u;
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v == fa[u]) {dis[1][u] = dis[1][fa[u]] + E[i].val;fir += E[i].val;}
else dis[0][v] = dis[0][u] + E[i].val;
}
dp[u] = mp(0,u);
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v != fa[u]) {
fa[v] = u;
dfs(v);
siz[u] += siz[v];
if(E[i].val + dp[v].fi + dp[u].fi - dis[1][u] + dis[0][u] > mval) {
mval = E[i].val + dp[v].fi + dp[u].fi - dis[1][u] + dis[0][u];
S = dp[u].se;T = dp[v].se;
}
if(dp[v].fi + E[i].val > dp[u].fi) {
dp[u].fi = dp[v].fi + E[i].val;dp[u].se = dp[v].se;
}
}
}
}
void update(int u) {
if(tr[u << 1].mv > tr[u << 1 | 1].mv) {
tr[u].mv = tr[u << 1].mv;
tr[u].pos = tr[u << 1].pos;
}
else {
tr[u].mv = tr[u << 1 | 1].mv;
tr[u].pos = tr[u << 1 | 1].pos;
}
}
void addlz(int u,int64 v) {
tr[u].mv += v;tr[u].lz += v;
}
void pushdown(int u) {
if(tr[u].lz) {
addlz(u << 1,tr[u].lz);
addlz(u << 1 | 1,tr[u].lz);
tr[u].lz = 0;
}
}
void build(int u,int l,int r) {
tr[u].l = l;tr[u].r = r;
if(l == r) {
tr[u].mv = dis[0][line[l]];tr[u].pos = line[l];
return;
}
int mid = (l + r) >> 1;
build(u << 1,l,mid);
build(u << 1 | 1,mid + 1,r);
update(u);
}
void Add(int u,int l,int r,int64 v) {
if(tr[u].l == l && tr[u].r == r) {addlz(u,v);return;}
pushdown(u);
int mid = (tr[u].l + tr[u].r) >> 1;
if(r <= mid) Add(u << 1,l,r,v);
else if(l > mid) Add(u << 1 | 1,l,r,v);
else {Add(u << 1,l,mid,v);Add(u << 1 | 1,mid + 1,r,v);}
update(u);
}
int64 Query(int u,int pos) {
if(tr[u].l == tr[u].r) return tr[u].mv;
pushdown(u);
int mid = (tr[u].l + tr[u].r) >> 1;
if(pos <= mid) return Query(u << 1,pos);
else return Query(u << 1 | 1,pos);
}
void Delete(int u) {
int pre = 0;
while(u && !vis[u]) {
int64 t = Query(1,dfn[u]);
if(!pre) Add(1,dfn[u],dfn[u] + siz[u] - 1,-t);
else {
Add(1,dfn[u],dfn[pre] - 1,-t);
if(dfn[pre] + siz[pre] <= dfn[u] + siz[u] - 1)
Add(1,dfn[pre] + siz[pre],dfn[u] + siz[u] - 1,-t);
}
vis[u] = 1;
pre = u;u = fa[u];
}
}
void More(int x) {
ans[x] = ans[x - 1] - tr[1].mv;
Delete(tr[1].pos);
}
void Main() {
dfs(1);
ans[2] = all - (fir + mval);
memset(dis,0,sizeof(dis));
fa[S] = 0;idx = 0;
dfs(S);
build(1,1,N);
Delete(T);
} }
void Solve() {
read(N);
int a,b,c,d;
for(int i = 1 ; i < N ; ++i) {
read(a);read(b);read(c);read(d);
add(a,b,c);
add(b,a,d);
all += c;all += d;
}
one::Main();
if(N >= 2) two::Main();
for(int i = 3 ; i <= N ; ++i) {
two::More(i);
}
int Q;
read(Q);
for(int i = 1 ; i <= Q ; ++i) {
read(a);
out(ans[a]);enter;
}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}

【LOJ】#3036. 「JOISC 2019 Day3」指定城市的更多相关文章

  1. 「JOISC 2019 Day3」穿越时空 Bitaro

    「JOISC 2019 Day3」穿越时空 Bitaro 题解: ​ 不会处理时间流逝,我去看了一眼题解的图,最重要的转换就是把(X,Y)改成(X,Y-X)这样就不会斜着走了. ​ 问题变成二维平面上 ...

  2. @loj - 3039@ 「JOISC 2019 Day4」蛋糕拼接 3

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 今天是 IOI 酱的生日,所以她的哥哥 JOI 君给她预定了一个 ...

  3. 【LOJ】#3034. 「JOISC 2019 Day2」两道料理

    LOJ#3034. 「JOISC 2019 Day2」两道料理 找出最大的\(y_{i}\)使得\(sumA_{i} + sumB_{y_i} \leq S_{i}\) 和最大的\(x_{j}\)使得 ...

  4. 【LOJ】#3032. 「JOISC 2019 Day1」馕

    LOJ#3032. 「JOISC 2019 Day1」馕 处理出每个人把馕切成N段,每一段快乐度相同,我们选择第一个排在最前的人分给他的第一段,然后再在未选取的的人中选一个第二个排在最前的切一下,并把 ...

  5. 【LOJ】#3033. 「JOISC 2019 Day2」两个天线

    LOJ#3033. 「JOISC 2019 Day2」两个天线 用后面的天线更新前面的天线,线段树上存历史版本的最大值 也就是线段树需要维护历史版本的最大值,后面的天线的标记中最大的那个和最小的那个, ...

  6. 【LOJ】#3031. 「JOISC 2019 Day1」聚会

    LOJ#3031. 「JOISC 2019 Day1」聚会 听说随机可过? 我想了很久想了一个不会被卡的做法,建出前\(u - 1\)个点的虚树,然后找第\(u\)个点的插入位置,就是每次找一条最长链 ...

  7. 【LOJ】#3030. 「JOISC 2019 Day1」考试

    LOJ#3030. 「JOISC 2019 Day1」考试 看起来求一个奇怪图形(两条和坐标轴平行的线被切掉了一个角)内包括的点个数 too naive! 首先熟练的转化求不被这个图形包含的个数 -- ...

  8. loj 3014「JOI 2019 Final」独特的城市

    loj 我本来是直接口胡了一个意思一样的做法的,但是因为觉得有点假+实现要用并查集(?)就卡了好一会儿... 对于一个点\(x\)来说,独特的点一定在它的最长链上,如果有独特的点不在最长链上,那么最长 ...

  9. 「JOISC 2019 Day4」蛋糕拼接 3

    loj 3039 NKOJ Description \(n\)个蛋糕,每个蛋糕有\(w_i,h_i\).选\(m\)个蛋糕满足\(\sum\limits_{j=1}^mw_{k_j}-\sum\lim ...

随机推荐

  1. 配置魔药(DP)

    配置魔药 [问题描述] 在<Harry Potter and the Chamber of Secrets>中,Ron的魔杖因为坐他老爸的Flying Car撞到了打人柳,不幸被打断了,从 ...

  2. JavaWeb_(Spring框架)在Struts+Hibernate框架中引入Spring框架

    spring的功能:简单来说就是帮我们new对象,什么时候new对象好,什么时候销毁对象. 在MySQL中添加spring数据库,添加user表,并添加一条用户数据 使用struts + hibern ...

  3. vue-router的两种动态路由

    第一种实质上不能算动态路由,充其量算是参数的传递 https://www.jianshu.com/p/f499d9f64958 第二种是真正的动态路由,利用 router.addRoutes()设置动 ...

  4. javascript操作表单

    表单元素除了可以运用上述所有DOM相关操作外,为了简化,还有一系列自己的属性和方法. 表单除了支持鼠标,键盘,更改和html时间之外,还支持一些表单特有的事件,如focus,change,blur等等 ...

  5. Guava中Lists.partition(List, size) 方法懒划分/懒分区

    目录 Guava中Lists.partition(List, size) 方法懒划分/懒分区 背景 分析 总结 Guava中Lists.partition(List, size) 方法懒划分/懒分区 ...

  6. centos7搭建hadoop-2.7.3,zookeeper-3.4.6,hbase-1.2.5(root用户)

    环境:[centos7.hadoop-2.7.3.zookeeper-3.4.6.hbase-1.2.5] 两个节点:[主节点,主机名为Master,用户为root:从节点,主机名为Slave,用户为 ...

  7. mac安装phpmysql

    1.百度搜“phpmadmin”,还是一样,第二个因为是PC版本,不能用,点击第一个连接,去phpmyadmin的官网. 2.下载完毕后,进入到下载文件保存目录,双击压缩包,压缩包则会自动解压. 3. ...

  8. 数据结构之栈(stack)

    1,栈的定义 栈:先进后出的数据结构,如下图所示,先进去的数据在底部,最后取出,后进去的数据在顶部,最先被取出. 栈常用操作: s=Stack() 创建栈 s.push(item) 将数据item放在 ...

  9. CentOS7设置开机启动方式(图形界面/命令行界面)

    CentOS 7由于使用systemd而不是init,所以不能通过修改inittab文件来修改开机启动模式. 先使用ctrl+alt+f2切换到命令行模式,然后输入命令:systemctl set-d ...

  10. nfs服务共享,解决文件没有权限访问问题

    最近在了解一些服务权限的设置,突然就被这个nfs服务的权限给绊住了.当你挂载上服务器上的共享目录 时,却无法访问里面的一些内容.内心满满的忧桑...经过努力奋斗几分钟终于搞明白了. 无法访问的原因:因 ...