zoukankan      html  css  js  c++  java
  • [NOIP2018]保卫王国

    倍增写法

    #include <bits/stdc++.h>
    
    #define rep(i, a, b) for (int i = a, i##end = b; i <= i##end; ++i)
    #define per(i, a, b) for (int i = a, i##end = b; i >= i##end; --i)
    #define rep0(i, a) for (int i = 0, i##end = a; i < i##end; ++i)
    #define per0(i, a) for (int i = (int)a-1; ~i; --i)
    #define chkmax(a, b) a = std::max(a, b)
    #define chkmin(a, b) a = std::min(a, b)
    #define x first
    #define y second
    #define pb push_back
    #define mp std::make_pair
    #define enter putchar('
    ')
    
    typedef long long ll;
    
    using std::max;
    using std::swap;
    
    int read() {
    	int w = 0, f = 1; char c;
    	while (!isdigit(c = getchar())) c == '-' && (f == -1);
    	while (isdigit(c)) w = w*10+(c^48), c = getchar();
    	return w * f;
    }
    
    const int N = 100005;
    const ll oo = 1ll<<50;
    
    int n, m, p[N];
    ll sgm = 0;
    
    struct Edge { int v, nxt; } e[N*2];
    int G[N], edges = 0;
    void adde(int u, int v) { e[edges++] = (Edge){v, G[u]}; G[u] = edges-1; }
    
    ll f[2][N], g[2][2][18][N], h[18][N]; int d[N];
    void dfs1(int u, int fa) {
    	for (int i = G[u], v; ~i; i = e[i].nxt) {
    		if ((v = e[i].v) == fa) continue;
    		dfs1(v, u);
    		f[0][u] += max(f[0][v], f[1][v]); f[1][u] += f[0][v];
    	}
    	f[1][u] += p[u];
    }
    void dfs2(int u, int fa) {
    	d[u] = d[h[0][u] = fa]+1;
    	g[0][0][0][u] = g[1][0][0][u] = f[0][fa] - max(f[0][u], f[1][u]);
    	g[0][1][0][u] = f[1][fa] - f[0][u];
    	g[1][1][0][u] = -oo;
    	rep(i, 1, 17) {
    		h[i][u] = h[i-1][h[i-1][u]];
    		g[0][0][i][u] = max(g[0][0][i-1][u]+g[0][0][i-1][h[i-1][u]], g[0][1][i-1][u]+g[1][0][i-1][h[i-1][u]]);
    		g[0][1][i][u] = max(g[0][0][i-1][u]+g[0][1][i-1][h[i-1][u]], g[0][1][i-1][u]+g[1][1][i-1][h[i-1][u]]);
    		g[1][0][i][u] = max(g[1][0][i-1][u]+g[0][0][i-1][h[i-1][u]], g[1][1][i-1][u]+g[1][0][i-1][h[i-1][u]]);
    		g[1][1][i][u] = max(g[1][0][i-1][u]+g[0][1][i-1][h[i-1][u]], g[1][1][i-1][u]+g[1][1][i-1][h[i-1][u]]);
    	}
    	for (int i = G[u]; ~i; i = e[i].nxt)
    		if (e[i].v != fa) dfs2(e[i].v, u);
    }
    
    void jump(ll &f0, ll &f1, int &x, int i) {
    	ll g0 = max(f0+g[0][0][i][x], f1+g[1][0][i][x]), g1 = max(f0+g[0][1][i][x], f1+g[1][1][i][x]);
    	f0 = g0, f1 = g1; x = h[i][x];
    }
    ll dp(int x, int a, int y, int b) {
    	if (d[x] < d[y]) swap(x, y), swap(a, b);
    	ll f0, f1;
    	a ? (f0 = -oo, f1 = f[1][x]) : (f0 = f[0][x], f1 = -oo);
    	for (int i = 0, j = d[x]-d[y]; j; j >>= 1, i++)
    		if (j & 1) jump(f0, f1, x, i);
    	if (x == y) {
    		b ? (f0 = -oo) : (f1 = -oo);
    		for (int i = 0, j = d[x]-1; j; j >>= 1, i++)
    			if (j & 1) jump(f0, f1, x, i);
    		return max(f0, f1);
    	}
    	ll g0, g1;
    	b ? (g0 = -oo, g1 = f[1][y]) : (g0 = f[0][y], g1 = -oo);
    	per0(i, 18)
    		if (h[i][x] != h[i][y])	jump(f0, f1, x, i), jump(g0, g1, y, i);
    	int u = h[0][x]; ll h0 = f[0][u]-max(f[0][x], f[1][x])-max(f[0][y], f[1][y])+max(f0, f1)+max(g0, g1), h1 = f[1][u]-f[0][x]-f[0][y]+f0+g0;
    	for (int i = 0, j = d[u]-1; j; j >>= 1, i++)
    		if (j & 1) jump(h0, h1, u, i);
    	return max(h0, h1);
    }
    
    int main() {
    	n = read(), m = read(); read();
    	rep(i, 1, n) p[i] = read(), sgm += p[i];
    	memset(G, -1, sizeof G);
    	rep(i, 2, n) { int u = read(), v = read(); adde(u, v), adde(v, u); }
    	dfs1(1, 0), dfs2(1, 0);
    	while (m--) {
    		int x = read(), a = read(), y = read(), b = read();
    		ll tot = dp(x, !a, y, !b);
    		printf("%lld
    ", tot < 0 ? -1 : sgm-tot);
    	}
    	return 0;
    }
    

    ddp写法

    这篇代码鸽了
    
  • 相关阅读:
    周末之个人杂想(十三)
    PowerTip of the DaySorting Multiple Properties
    PowerTip of the DayCreate Remoting Solutions
    PowerTip of the DayAdd Help to Your Functions
    PowerTip of the DayAcessing Function Parameters by Type
    PowerTip of the DayReplace Text in Files
    PowerTip of the DayAdding Extra Information
    PowerTip of the DayPrinting Results
    Win7下IIS 7.5配置SSAS(2008)远程访问
    PowerTip of the DayOpening Current Folder in Explorer
  • 原文地址:https://www.cnblogs.com/ac-evil/p/13922966.html
Copyright © 2011-2022 走看看