树上待修莫队模板,另一个平台60分求调
查看原帖
树上待修莫队模板,另一个平台60分求调
956071
Xiongzx楼主2023/4/20 16:05
#include <bits/stdc++.h>

#define rep(i, a, b) for(int i = (a); i <= (b); i++)
#define pre(i, a, b) for(int i = (a); i >= (b); i--)
#define Ede(i, u) for(int i = h[u]; i; i = ne[i])
#define go(i, a) for(auto i : a)
//#define int long long
#define LL long long
#define ULL unsigned long long
#define PII pair<int, int>
#define PIL pair<int, long long>
#define PLI pair<long long, int>
#define PLL pair<long long, long long>
#define mp make_pair
#define eb emplace_back
#define opb pop_back
#define pb push_back
#define pf push_front
#define fi first
#define se second
#define sf scanf
#define prf printf
#define el putchar('\n')
#define mms(arr, n) memset(arr, n, sizeof(arr))
#define mmc(arr1, arr2) memcpy(arr1, arr2, sizeof(arr2))
const int inf = 0x3f3f3f3f;

template <typename T> inline void rd(T &x){
	x = 0; bool f = true; char ch = getchar();
	while(ch < '0' || ch > '9'){ if(ch == '-') f = false; ch = getchar();}
	while(ch >= '0' && ch <= '9'){ x = (x << 1) + (x << 3) + (ch ^ '0'); ch = getchar();}
	if(!f) x = -x;
}
template <typename T, typename ...Args> inline void rd(T &x, Args &...args){ rd(x); rd(args...);}

using namespace std;

const int N = 1e5 + 10, M = N << 1;
int n, q;
int a[N];
int h[N], e[M], ne[M], idx;
int siz;
void add(int a, int b){
	e[++idx] = b, ne[idx] = h[a], h[a] = idx;
}
struct Qu{
	int l, r;
	int pre, x, id;
}qu[N]; int qcnt;
bool cmp(Qu a, Qu b){
	if(a.l / siz != b.l / siz) return a.l < b.l;
	if(a.r / siz != b.r / siz) return a.r < b.r;
	return a.pre < b.pre;
}
struct M{
	int p, x, y;
}ops[N]; int T;

int ds[M], cnt;
int fa[N][20];
int dep[N];
int s[N], t[N]; //开始,结束 
void dfs(int u){
	dep[u] = dep[fa[u][0]] + 1;
	ds[++cnt] = u, s[u] = cnt;
	rep(i, 1, 19) fa[u][i] = fa[fa[u][i - 1]][i - 1];
	Ede(i, u){
		int v = e[i];
		if(v != fa[u][0]) fa[v][0] = u, dfs(v);
 	}
 	ds[++cnt] = u, t[u] = cnt;
}
int LCA(int x, int y){
	if(dep[x] < dep[y]) swap(x, y);
	for(int i = 19; i >= 0; i--){
		if(dep[fa[x][i]] >= dep[y]) x = fa[x][i];
	}
	if(x == y) return x;
	for(int i = 19; i >= 0; i--){
		if(fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];
	}
	return fa[x][0];
}
LL ans[N], res;
int ccnt[N];
int vis[N];
void Add(int x){ //值 
	res -= (LL)ccnt[x] * (ccnt[x] - 1) / 2;
	ccnt[x]++;
	res += (LL)ccnt[x] * (ccnt[x] - 1) / 2;	
}
void Del(int x){
	res -= (LL)ccnt[x] * (ccnt[x] - 1) / 2;
	ccnt[x]--;
	res += (LL)ccnt[x] * (ccnt[x] - 1) / 2;	
}
void upd(int x){ //编号 
	vis[x] ^= 1;
	if(vis[x]) Add(a[x]);
	else Del(a[x]);
}
void modify(int p, int x){
	if(vis[p]){
		Del(a[p]);
		Add(x);
	}
	a[p] = x;
}

int main(){
	/*
	freopen(".in", "r", stdin);
	freopen(".out", "w", stdout);
	*/
	rd(n, q); siz = (int)pow(q, 0.666);
	rep(i, 0, n - 1) rd(a[i]); 
	for(int i = 1, x, y; i <= n - 1; i++){
		rd(x, y);
		add(x, y), add(y, x);
	}
	dfs(0);
	rep(i, 1, q){
		int ins, x, y; rd(ins, x, y);
		if(ins == 1){
			T++;
			ops[T].p = x, ops[T].y = y;
		}else{
			++qcnt;
			int lca = LCA(x, y);
			if(x == lca || y == lca){
				if(s[x] > s[y]) swap(x, y);
				qu[qcnt].l = s[x], qu[qcnt].r = s[y];
			}else{
				if(t[x] > s[y]) swap(x, y);
				qu[qcnt].l = t[x], qu[qcnt].r = s[y];
				qu[qcnt].x = lca;
			}
			qu[qcnt].id = qcnt, qu[qcnt].pre = T; 
		}
	}
//	prf("test: %d\n", qcnt);
//	rep(i, 1, cnt) prf("ds[%d]: %d ", i, ds[i]); el;
//	prf("l: %d, r: %d\n", qu[1].l, qu[1].r);
//	prf("lca: %d pre: %d T: %d\n", qu[1].x, qu[1].pre, T);
	rep(i, 1, T) ops[i].x = a[ops[i].p], a[ops[i].p] = ops[i].y;
	int tm = T;
	sort(qu + 1, qu + qcnt + 1, cmp);
	for(int i = 1, l = qu[1].l, r = qu[1].l - 1; i <= qcnt; i++){
		while(l < qu[i].l) upd(ds[l++]);
		while(r > qu[i].r) upd(ds[r--]);
		while(l > qu[i].l) upd(ds[--l]);
		while(r < qu[i].r) upd(ds[++r]);
		if(qu[i].x) upd(qu[i].x);
		while(tm < qu[i].pre) tm++, modify(ops[tm].p, ops[tm].y);
		//modify(ops[i].p, ops[i].y, l, r);
		while(tm > qu[i].pre) modify(ops[tm].p, ops[tm].x), tm--;
		//modify(ops[i].p, ops[i].x, l, r)
		ans[qu[i].id] = res;
//		prf("id: %d, res: %d\n", qu[i].id, res);
		if(qu[i].x) upd(qu[i].x);
	}
	rep(i, 1, qcnt) prf("%lld\n", ans[i]);
	return 0;
}





2023/4/20 16:05
加载中...