题目大意:

emmmmm


题解:

QAQ


#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std; #define ll long long
#define ri register int
#define rep(io, st, ed) for(ri io = st; io <= ed; io ++)
#define drep(io, ed, st) for(ri io = ed; io >= st; io --) #define gc getchar
inline int read() {
int p = 0, w = 1; char c = gc();
while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); }
while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc();
return p * w;
} const int sid = 5e5 + 5;
const ll inf = 1e17; char mm[50];
int n, m, id, cnp, tim;
int ls[sid], rs[sid], rt[sid];
int cap[sid], nxt[sid], node[sid];
int sz[sid], son[sid], fa[sid], anc[sid];
int dfn[sid], ind[sid], L[sid], V[sid]; ll g[sid][2];
struct Mar {
ll dp[2][2];
inline ll* operator [] (const int x) { return dp[x]; }
} F[sid]; inline void addedge(int u, int v) {
nxt[++ cnp] = cap[u]; cap[u] = cnp; node[cnp] = v;
} #define cur node[i]
inline void dfs(int o) {
sz[o] = 1;
for(int i = cap[o]; i; i = nxt[i])
if(cur != fa[o]) {
fa[cur] = o; dfs(cur);
sz[o] += sz[cur];
if(sz[cur] > sz[son[o]]) son[o] = cur;
}
} inline void dfs(int o, int ac) {
anc[o] = ac; L[ac] ++;
dfn[o] = ++ tim; ind[tim] = o;
if(!son[o]) return; dfs(son[o], ac);
for(int i = cap[o]; i; i = nxt[i])
if(cur != fa[o] && cur != son[o])
dfs(cur, cur);
} inline void upd(int o) {
int lc = ls[o], rc = rs[o];
F[o][0][0] = min(F[rc][0][0] + F[lc][0][0], F[rc][0][1] + F[lc][1][0]);
F[o][0][1] = min(F[rc][0][0] + F[lc][0][1], F[rc][0][1] + F[lc][1][1]);
F[o][1][0] = min(F[rc][1][0] + F[lc][0][0], F[rc][1][1] + F[lc][1][0]);
F[o][1][1] = min(F[rc][1][0] + F[lc][0][1], F[rc][1][1] + F[lc][1][1]);
} inline void build(int &o, int l, int r) {
o = ++ id;
if(l == r) {
int u = ind[l];
F[o][0][0] = F[o][1][0] = g[u][1];
F[o][0][1] = g[u][0];
F[o][1][1] = inf;
return;
}
int mid = (l + r) >> 1;
build(ls[o], l, mid);
build(rs[o], mid + 1, r);
upd(o);
} inline void mdf(int o, int l, int r, int p) {
if(l == r) {
int u = ind[l];
F[o][0][0] = F[o][1][0] = g[u][1];
F[o][0][1] = g[u][0];
F[o][1][1] = inf;
return;
}
int mid = (l + r) >> 1;
if(p <= mid) mdf(ls[o], l, mid, p);
else mdf(rs[o], mid + 1, r, p);
upd(o);
} inline void build(int o) {
int leaf = 0;
g[o][0] = 0; g[o][1] = V[o];
for(int i = cap[o]; i; i = nxt[i])
if(cur != fa[o]) {
leaf = 1; build(cur);
if(cur == son[o]) continue;
g[o][0] += F[rt[cur]][0][0];
g[o][1] += min(F[rt[cur]][0][0], F[rt[cur]][0][1]);
}
if(anc[o] == o)
build(rt[o], dfn[o], dfn[o] + L[o] - 1);
} inline void mdf(int o, int opt, int nx) {
int now = anc[o], up = fa[now], lst = o;
if(opt == 1) g[o][0] += inf * nx;
else g[o][1] += inf * nx;
while(lst) {
g[up][0] -= F[rt[now]][0][0];
g[up][1] -= min(F[rt[now]][0][0], F[rt[now]][0][1]);
mdf(rt[now], dfn[now], dfn[now] + L[now] - 1, dfn[lst]);
g[up][0] += F[rt[now]][0][0];
g[up][1] += min(F[rt[now]][0][0], F[rt[now]][0][1]);
lst = up; now = anc[up]; up = fa[now];
}
} inline void solve() {
int a = read(), x = read(), b = read(), y = read();
mdf(a, x, 1); mdf(b, y, 1);
ll ans = min(F[rt[1]][0][0], F[rt[1]][0][1]);
ans = min(F[rt[1]][0][0], F[rt[1]][0][1]);
if(ans >= 1e15) printf("-1\n");
else printf("%lld\n", ans);
mdf(a, x, -1); mdf(b, y, -1);
} int main() {
n = read(); m = read(); scanf("%s", mm + 1);
rep(i, 1, n) V[i] = read();
rep(i, 2, n) {
int u = read(), v = read();
addedge(u, v); addedge(v, u);
}
dfs(1);
dfs(1, 1);
build(1);
rep(i, 1, m) solve();
return 0;
}

大家都会写的题,不是吗?

luoguP5024 保卫王国 动态dp的更多相关文章

  1. LuoguP5024 保卫王国(动态DP,LCT)

    最小权覆盖集 = 全集 - 最大权独立集 强制取点.不取点可以使用把权值改成正无穷或负无穷实现 接下来就是经典的"动态最大权独立集"了 O(nlogn). 这不是我说的,是immo ...

  2. luogu5024 [NOIp2018]保卫王国 (动态dp)

    可以直接套动态dp,但因为它询问之间相互独立,所以可以直接倍增记x转移到fa[x]的矩阵 #include<bits/stdc++.h> #define CLR(a,x) memset(a ...

  3. JZOJ5966. [NOIP2018TGD2T3] 保卫王国 (动态DP做法)

    题目大意 这还不是人尽皆知? 有一棵树, 每个节点放军队的代价是\(a_i\), 一条边连接的两个点至少有一个要放军队, 还有\(q\)次询问, 每次规定其中的两个一定需要/不可放置军队, 问这样修改 ...

  4. 【NOIP2018】保卫王国 动态dp

    此题场上打了一个正确的$44pts$,接着看错题疯狂$rush$“正确”的$44pts$,后来没$rush$完没将之前的代码$copy$回去,直接变零分了..... 这一题我们显然有一种$O(nm)$ ...

  5. BZOJ 5466: [Noip2018]保卫王国 动态DP

    Code: // luogu-judger-enable-o2 #include<bits/stdc++.h> #define ll long long #define lson (now ...

  6. P5024 保卫王国(动态dp/整体dp/倍增dp)

    做法(倍增) 最好写的一种 以下0为不选,1为选 \(f_{i,0/1}\)为\(i\)子树的最小值,\(g_{i,0/1}\)为除i子树外的最小值 \(fh_{i,j,0/1,0/1}\)为确定\( ...

  7. luoguP5024 保卫王国

    题目链接 问题分析 其实是比较明显的动态DP. 懒于再推一遍式子,直接用 最小权点覆盖=全集-最大权独立集,然后就和这道题一样了.题解可以看这里. 然后必须选或者不选的话,就直接把相应的点权变成\(- ...

  8. P5024 保卫王国[倍增+dp]

    窝当然不会ddp啦,要写这题当然是考虑优化裸dp啦,但是这题非常麻烦,于是变成了黑题. 首先,这个是没有上司的舞会模型,求图的带权最大独立集. 不考虑国王的限制条件,有 \[ dp[x][0]+=dp ...

  9. Uoj 441 保卫王国

    Uoj 441 保卫王国 动态 \(dp\) .今天才来写这个题. 设 \(f[u][0/1]\) 表示子树 \(u\) 中不选/选 \(u\) 时的最小权值和,显然有:\(f[u][0]=\sum ...

随机推荐

  1. spring-boot-单元测试参数数

    简单案例 @RunWith(Parameterized.class) public class ParameterTest { // 2.声明变量存放预期值和测试数据 private String f ...

  2. JSON数据填充表格——(三)

    1.定义页面请求JSON的按钮与定义一个带表头的表格  请求数据的按钮 <button class="btn btn-primary search_bar_button floatR& ...

  3. Spring4笔记5--基于注解的DI(依赖注入)

    基于注解的DI(依赖注入): 对于 DI 使用注解,将不再需要在 Spring 配置文件中声明 Bean 实例.只需要在 Spring 配置文件中配置组件扫描器,用于在指定的基本包中扫描注解. < ...

  4. 渗透测试===kali linux的安装

    方法一: kali linux 安装在本地的vitural box 或者 wm ware中 方法二: 安装在移动硬盘或者储存卡中,插到电脑就能用

  5. 【Linux】Linux基本命令扫盲【转】

    转自:http://www.cnblogs.com/lcw/p/3762927.html [VI使用] 1.在命令行模式     :在vi编辑器中将光标放在函数上,shift + k 可直接man手册 ...

  6. Linux USB驱动框架分析 【转】

    转自:http://blog.chinaunix.net/uid-11848011-id-96188.html 初次接触与OS相关的设备驱动编写,感觉还挺有意思的,为了不至于忘掉看过的东西,笔记跟总结 ...

  7. 深入理解MySQL的并发控制、锁和事务【转】

    本文主要是针对MySQL/InnoDB的并发控制和加锁技术做一个比较深入的剖析,并且对其中涉及到的重要的概念,如多版本并发控制(MVCC),脏读(dirty read),幻读(phantom read ...

  8. Python [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed 解决方法

    一个搭建在SAE上的Django应用,使用新浪微博提供的Python SDK已经稳定运行一年有余,但最近开始持续出现微博认证失败的状况. 摘录微博python SDK的错误提示如下所示: ERROR: ...

  9. Elasticsearch 邻近查询示例

    Elasticsearch 邻近查询示例(全切分分词) JAVA API方式: SpanNearQueryBuilder span = QueryBuilders.spanNearQuery(); s ...

  10. CentOS/Linux 网卡设置 IP地址配置

    CentOS/Linux下设置IP地址 1:临时修改:1.1:修改IP地址# ifconfig eth0 192.168.100.100 1.2:修改网关地址# route add default g ...