3.67KB of shit for debug
查看原帖
3.67KB of shit for debug
148438
Linshey楼主2020/10/7 19:53

I am so laji,zhen de tiao bu chu lai le!Please help me!Thank you so much!(There's also somegin wrong with my conputer so I can't type any Cinese character!awsl!)


#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
const int maxn = 1e5 + 1e2;
const int INF = 998244353;

struct Matrix
{
	int u00, u01, u10, u11;


	Matrix()
	{
		u00 = u01 = u10 = u11 = 0;
	}

	Matrix(int a, int b, int c, int d)
	{
		u00 = a; u01 = b; u10 = c; u11 = d;
	}

	Matrix operator *(const Matrix& b) const
	{
		Matrix c;
		c.u00 = max(u00 + b.u00, u01 + b.u10);
		c.u01 = max(u00 + b.u01, u01 + b.u11);
		c.u10 = max(u10 + b.u00, u11 + b.u10);
		c.u11 = max(u10 + b.u01, u11 + b.u11);
		return c;
	}
};

Matrix I(0, -INF, -INF, 0);

Matrix tree[maxn * 4];

void update(int x, int l, int r, int pos, Matrix k)
{
	if (l == r)
	{
		tree[x] = k;
		return;
	}
	int mid = (l + r) >> 1;
	if (pos <= mid)
	{
		update(x << 1, l, mid, pos, k);
	}
	else
	{
		update(x << 1 | 1, mid + 1, r, pos, k);
	}
	tree[x] = tree[x << 1] * tree[x << 1 | 1];
}

Matrix query(int x, int l, int r, int ll, int rr)
{
	if (ll > rr) return I;
	if (ll <= l && r <= rr)
	{
		return tree[x];
	}
	int mid = (l + r) >> 1;
	if (rr <= mid)
	{
		return query(x << 1, l, mid, ll, rr);
	}
	else if (ll > mid)
	{
		return query(x << 1 | 1, mid + 1, r, ll, rr);
	}
	return query(x << 1, l, mid, ll, rr) *
		query(x << 1 | 1, mid + 1, r, ll, rr);
}

int n, m, a[maxn]; vector<int> T[maxn];

void init()
{
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
	}
	for (int i = 1; i < n; i++)
	{
		int u, v;
		cin >> u >> v;
		T[u].push_back(v);
		T[v].push_back(u);
	}
}

int sze[maxn], hvy[maxn], fat[maxn];

void dfs1(int x, int fa)
{
	fat[x] = fa;
	sze[x] = 1;
	for (auto s : T[x])
	{
		if (s == fa) continue;
		dfs1(s, x);
		sze[x] += sze[s];
		if (sze[hvy[x]] < sze[s])
		{
			hvy[x] = s;
		}
	}
}

int dfn[maxn], top[maxn], dwn[maxn], cnt;

void dfs2(int x, int tp)
{
	dfn[x] = ++cnt;
	top[x] = tp;
	dwn[x] = x;
	if (hvy[x])
	{
		dfs2(hvy[x], tp);
		dwn[x] = dwn[hvy[x]];
	}
	for (auto s : T[x])
	{
		if (s == fat[x]) continue;
		if (s == hvy[x]) continue;
		dfs2(s, s);
	}
}

int f[maxn][2], g[maxn][2];

void dp(int x)
{
	g[x][1] = a[x];
	if (!hvy[x])
	{
		f[x][1] = a[x];
		return;
	}
	for (auto s : T[x])
	{
		if (s == fat[x]) continue;
		dp(s);
		g[x][0] += max(f[s][0], f[s][1]);
		g[x][1] += f[s][0];
	}
	f[x][0] = g[x][0];
	f[x][1] = g[x][1];
	g[x][0] -= max(f[hvy[x]][0], f[hvy[x]][1]);
	g[x][1] -= f[hvy[x]][1];
	Matrix ts(g[x][0], g[x][1], g[x][0], -INF);
	update(1, 1, n, dfn[x], ts);
}

void update(int x, int y)
{
	g[x][1] -= a[x] - y;
	f[x][1] -= a[x] - y;
	a[x] = y;
	Matrix ts(g[x][0], g[x][1], g[x][0], -INF);
	update(1, 1, n, dfn[x], ts);
	while (fat[top[x]])
	{
		Matrix dn(f[dfn[dwn[x]]][0], f[dfn[dwn[x]]][1], 0, 0);
		Matrix ts = query(1, 1, n, dfn[dwn[x]] - 1, dfn[x]);
		Matrix nw = dn * ts;
		g[fat[top[x]]][1] -= f[top[x]][0];
		g[fat[top[x]]][0] -= max(f[top[x]][0], f[top[x]][1]);
		f[fat[top[x]]][1] -= f[top[x]][0];
		f[fat[top[x]]][0] -= max(f[top[x]][0], f[top[x]][1]);
		f[top[x]][0] = nw.u00;
		f[top[x]][1] = nw.u01;
		g[fat[top[x]]][1] += f[top[x]][0];
		g[fat[top[x]]][0] += max(f[top[x]][0], f[top[x]][1]);
		f[fat[top[x]]][1] += f[top[x]][0];
		f[fat[top[x]]][0] += max(f[top[x]][0], f[top[x]][1]);
		Matrix up(g[fat[top[x]]][0], g[fat[top[x]]][1], g[fat[top[x]]][0], -INF);
		update(1, 1, n, dfn[fat[top[x]]], up);
		x = fat[top[x]];
	}
	Matrix dn(f[x][0], f[x][1], 0, 0);
	Matrix nw = dn * query(1, 1, n, dfn[x] - 1, dfn[1]);
	cout << max(nw.u00, nw.u01) << endl;
}

int main()
{
	init();
	dfs1(1, 0);
	dfs2(1, 1);
	dp(1);
	for (int i = 1; i <= m; i++)
	{
		int x, y;
		cin >> x >> y;
		update(x, y);
	}
	return 0; 
}
2020/10/7 19:53
加载中...