点分树板子求调~
查看原帖
点分树板子求调~
204989
_Iva楼主2022/10/28 10:36
#include<bits/stdc++.h>
using namespace std;
#define ll long long
inline int rd()
{
	int x = 0, f = 0; char v = 0;
	while(!isdigit(v)) v = getchar(), f ^= v == '-';
	while(isdigit(v)) x = (x << 1) + (x << 3) + (v ^ 48), v = getchar();
	return f ? -x : x; 
}
inline void write(int x)
{
	if(x < 0) putchar('-') , x = -x;
	if(x > 9) write(x / 10);
	putchar(x % 10 ^ 48);
}
const int N = 1e5 + 10;
int hed[N], nxt[N << 1], to[N << 1], edtot;
inline void addedge(int u, int v) {nxt[++edtot] = hed[u], hed[u] = edtot, to[edtot] = v;}
int n, qq, q[N];
int dep[N], sze[N], dis[N], son[N], faa[N], top[N];
inline void dfs0(int u, int f)
{
	sze[u] = 1, dep[u] = dep[f] + 1, faa[u] = f;
	int v;
	for(int e = hed[u]; e; e = nxt[e]) if((v = to[e]) ^ f)
	{
		dis[v] = dis[u] + 1, dfs0(v, u);
		sze[u] += sze[v];
		if(sze[v] > sze[son[u]]) son[u] = v;
	}
}
inline void dfs2(int u, int f)
{
	top[u] = u ^ son[f] ? u : top[f];
	if(son[u]) dfs2(son[u], u);
	int v;
	for(int e = hed[u]; e; e = nxt[e]) if((v = to[e]) ^ f && v ^ son[u])
	    dfs2(v, u);
}
inline int LCA(int u, int v)
{
	while(top[u] ^ top[v])
	{
		if(dep[top[u]] < dep[top[v]]) u ^= v ^= u ^= v;
		u = faa[top[u]];
	}
	return dep[u] < dep[v] ? u : v;
}
inline int dist(int u, int v) {return dis[u] + dis[v] - (dis[LCA(u, v)] << 1);}

int rt, S, vis[N], mxsze[N];
inline void getrt(int u, int f)
{
	int v;
	sze[u] = 1, mxsze[u] = 0;
	for(int e = hed[u]; e; e = nxt[e]) if(!vis[v = to[e]] && v ^ f)
	{
		getrt(v, u), sze[u] += sze[v];
		mxsze[u] = max(mxsze[u], sze[v]);
	}
	mxsze[u] = max(mxsze[u], S - sze[u]);
	if(!rt || mxsze[u] < mxsze[rt]) rt = u;
}

int fa[N];
inline void divtree(int u)
{
	vis[u] = 1;
	int v;
	for(int e = hed[u]; e; e = nxt[e]) if(!vis[v = to[e]])
		rt = 0, S = sze[v], getrt(v, 0), getrt(rt, 0), fa[rt] = u, divtree(rt);
}
int a[N];

int nwnd;
int lc[N << 6], rc[N << 6], sum1[N << 6], sum2[N << 6];
inline void add1(int &p, int l, int r, int qv, int v)
{
	if(!p) p = ++nwnd;
	if(l == r) return (void) (sum1[p] += v);
	int mid = (l + r) >> 1;
	if(qv <= mid) add1(lc[p], l, mid, qv, v);
	else add1(rc[p], mid + 1, r, qv, v);
	sum1[p] = sum1[lc[p]] + sum1[rc[p]];
}
inline void add2(int &p, int l, int r, int qv, int v)
{
	if(!p) p = ++nwnd;
	if(l == r) return (void) (sum2[p] += v);
	int mid = (l + r) >> 1;
	if(qv <= mid) add2(lc[p], l, mid, qv, v);
	else add2(rc[p], mid + 1, r, qv, v);
	sum2[p] = sum2[lc[p]] + sum2[rc[p]];
}
inline int qry1(int p, int l, int r, int ql, int qr)
{
	if(!sum1[p]) return 0;
	if(ql <= l && r <= qr) return sum1[p];
	int mid = (l + r) >> 1, res = 0;
	if(ql <= mid) res = qry1(lc[p], l, mid, ql, qr);
	if(qr > mid) res += qry1(rc[p], mid + 1, r, ql, qr);
	return res;
}
inline int qry2(int p, int l, int r, int ql, int qr)
{
	if(!sum2[p]) return 0;
	if(ql <= l && r <= qr) return sum2[p];
	int mid = (l + r) >> 1, res = 0;
	if(ql <= mid) res = qry2(lc[p], l, mid, ql, qr);
	if(qr > mid) res += qry2(rc[p], mid + 1, r, ql, qr);
	return res;
}
int fl;
inline void mfy(int u, int v)
{
	cout << "\n\n";
	for(int f = u; f; f = fa[f])
	{
		if(dist(u, f) > 1e9) {fl = 1; break;}
		cout << dist(u, f) << "!\n";
		add1(f, 0, n - 1, dist(u, f), v);
		if(fa[f]) add2(f, 0, n - 1, dist(u, fa[f]), v);
	}
}
inline int qry(int u, int k)
{
	int res = 0;
	for(int f = u, lst = 0, d; f; lst = f, f = fa[u])
	{
		d = dist(u, f);
		if(k < d) continue;
		res += qry1(f, 0, n - 1, 0, min(n - 1, k - d));
		if(f ^ u) res -= qry2(lst, 0, n - 1, 0, min(n - 1, k - d));
	}
	return res;
}
int main()
{
	freopen("1.in", "r", stdin);
	freopen("1.out", "w", stdout);
	n = rd(), qq = rd(); nwnd = n;
	for(int i = 1; i <= n; ++i) a[i] = rd();
	for(int i = 1, u, v; i < n; ++i) u = rd(), v = rd(), addedge(u, v), addedge(v, u);
	dfs0(1, 0), dfs2(1, 0);
	rt = 0, S = n, getrt(1, 0), getrt(rt, 0), divtree(rt);
	//for(int i = 1; i <= n; ++i) cout << dep[i] << ' ' << faa[i] << ' ' << fa[i] << ' ' << top[i] << ' ' << son[i] << '\n';
	
	for(int i = 1; i <= n; ++i) mfy(i, a[i]);
	for(int i = 1, op, u, k, lst = 0; i <= qq; ++i)
	{
		cout << "&";
		op = rd(), u = rd() ^ lst, k = rd() ^ lst;
		if(op) mfy(u, k - a[u]), a[u] = k;
		//if(fl) break;
		//else write(lst = qry(u, k)), putchar('\n');
	}
	if(fl) cout << "%%";
	return 0;
}
2022/10/28 10:36
加载中...