• Luogu 4751 动态DP 模板


    题面

    动态求最大独立集

    题解

    树剖后用矩阵转移。
    具体见Tweetuzki的洛谷博客

    CODE

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    char cb[1<<15],*cs=cb,*ct=cb;
    #define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)
    inline void read(int &x) {
    	char ch; int flg=1; while(!isdigit(ch=getc()))if(ch=='-')flg=-flg;
    	for(x=ch-'0';isdigit(ch=getc());x=x*10+ch-'0'); x*=flg;
    }
    const int MAXN = 1000005;
    const int INF = 1000000000;
    int n, m, V[MAXN], fir[MAXN], nxt[MAXN<<1], to[MAXN<<1], cnt;
    inline void link(int u, int v) {
    	to[++cnt] = v; nxt[cnt] = fir[u]; fir[u] = cnt;
    	to[++cnt] = u; nxt[cnt] = fir[v]; fir[v] = cnt;
    }
    int tmr, fa[MAXN], dfn[MAXN], tp[MAXN], bt[MAXN], son[MAXN], sz[MAXN], seq[MAXN];
    struct mat {
    	int a[2][2];
    	int* operator[](int x) { return a[x]; }
    	mat operator*(const mat &o)const {
    		mat re;
    		for(int i = 0; i < 2; ++i)
    			for(int j = 0; j < 2; ++j)
    				re.a[i][j] = max(a[i][0]+o.a[0][j], a[i][1]+o.a[1][j]);
    		return re;
    	}
    }t[MAXN<<2], val[MAXN];
    void dfs1(int u, int ff) {
    	fa[u] = ff; sz[u] = 1;
    	for(int i = fir[u], v; i; i = nxt[i])
    		if((v=to[i]) != ff) {
    			dfs1(v, u), sz[u] += sz[v];
    			(sz[v] > sz[son[u]]) && (son[u] = v);
    		}
    }
    int f[MAXN][2];
    void dfs2(int u, int top) {
    	tp[u] = top; bt[top] = u;
    	seq[dfn[u]=++tmr] = u;
    	if(son[u]) dfs2(son[u], top);
    	for(int i = fir[u], v; i; i = nxt[i])
    		if((v=to[i]) != fa[u] && v != son[u])
    			dfs2(v, v);
    }
    void dp(int u) {
    	f[u][0] = 0; f[u][1] = V[u];
    	for(int i = fir[u], v; i; i = nxt[i])
    		if((v=to[i]) != fa[u])
    			dp(v),
    			f[u][0] += max(f[v][0], f[v][1]),
    			f[u][1] += f[v][0];
    }
    void build(int i, int l, int r) {
    	if(l == r) {
    		int f0 = 0, f1 = V[seq[l]];
    		for(int j = fir[seq[l]], v; j; j = nxt[j])
    			if((v=to[j]) != fa[seq[l]] && v != son[seq[l]])
    				f0 += max(f[v][0], f[v][1]),
    				f1 += f[v][0];
    		val[l] = t[i] = (mat){ {{f0, f0} , {f1, -INF}} };
    		return;
    	}
    	int mid = (l + r) >> 1;
    	build(i<<1, l, mid);
    	build(i<<1|1, mid+1, r);
    	t[i] = t[i<<1] * t[i<<1|1];
    }
    void update(int i, int l, int r, int x) {
    	if(l == r) { t[i] = val[l]; return; }
    	int mid = (l + r) >> 1;
    	if(x <= mid) update(i<<1, l, mid, x);
    	else update(i<<1|1, mid+1, r, x);
    	t[i] = t[i<<1] * t[i<<1|1];
    }
    mat query(int i, int l, int r, int x, int y) {
    	if(x == l && r == y) return t[i];
    	int mid = (l + r) >> 1;
    	if(y <= mid) return query(i<<1, l, mid, x, y);
    	if(x > mid) return query(i<<1|1, mid+1, r, x, y);
    	return query(i<<1, l, mid, x, mid) * query(i<<1|1, mid+1, r, mid+1, y);
    }
    void modify(int u, int W) {
    	val[dfn[u]][1][0] += W-V[u]; V[u]=W;
    	while(u) {
    		mat pre = query(1, 1, n, dfn[tp[u]], dfn[bt[tp[u]]]);
    		update(1, 1, n, dfn[u]);
    		mat now = query(1, 1, n, dfn[tp[u]], dfn[bt[tp[u]]]);
    		u = fa[tp[u]]; if(!u) return; int x = dfn[u];
    		int p0 = pre[0][0], p1 = pre[1][0];
    		int n0 = now[0][0], n1 = now[1][0];
    		val[x][0][0] = val[x][0][1] = val[x][0][0] + max(n0, n1) - max(p0, p1);
    		val[x][1][0] = val[x][1][0] + n0 - p0;
    	}
    }
    int main () {
    	read(n), read(m);
    	for(int i = 1; i <= n; ++i) read(V[i]);
    	for(int i = 1, u, v; i < n; ++i) read(u), read(v), link(u, v);
    	dfs1(1, 0), dfs2(1, 1), dp(1);
    	build(1, 1, n);
    	int x, y, lstans=0;
    	while(m--) {
    		read(x), read(y); x^=lstans; modify(x, y);
    		mat ans = query(1, 1, n, 1, dfn[bt[1]]);
    		printf("%d
    ", lstans=max(ans[0][0], ans[1][0]));
    	}
    }
    

    加强版只过80分

  • 相关阅读:
    游戏类型
    cocos2d-x lua 一些语法
    lua中ipairs和pairs
    lua的一些语法
    误删jre怎么办
    右键android工程的包名选择Build Path后怎么还原
    播放Armature动画
    接入第三方sdk出现了一些问题总结
    gettimeofday() 获取系统时间,精确到微秒 这个似乎只能在linux 下用,不能在windows 下用
    windows timeGetTime() 函数 获取系统从开机到现在的毫秒时间值
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039188.html
Copyright © 2020-2023  润新知