• luoguP5024 保卫王国 动态dp


    题目大意:

    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
    ");
    	else printf("%lld
    ", 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;
    }
    

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

  • 相关阅读:
    MMoE论文笔记
    李宏毅-ELMO, BERT, GPT
    vue 手写一个时间选择器
    this 的几种使用场景
    如何使用markdown编辑器编写文章
    sublime text 3 入门技巧与常见问题解决
    Flex布局介绍
    在github上实现页面托管预览功能
    数据挖掘经典算法——最大期望算法
    数据挖掘经典算法——先验算法
  • 原文地址:https://www.cnblogs.com/reverymoon/p/10164593.html
Copyright © 2020-2023  润新知