1. 程式人生 > 程式設計 >JS防抖節流函式的實現與使用場景

JS防抖節流函式的實現與使用場景

每個節點上開一個cnti陣列表示i這個數字出現了多少次,那麼節點i上出現最多的數字就是cnt陣列的最大值。

然後每次的操作可以調整為:

在u v上打一個+1的標記,在uv的lca上打一個-1的標記,在lca的父親上打一個-1的標記。

然後打完標記後從葉子開始啟發式的向上合併。

假設當前節點是u。

首先比較u的線段樹sz和u的兒子們的最大線段樹sz,小的往大的上面合併。

然後剩下的線段樹無腦往這個最大的線段樹上合併,那麼最終的線段樹就是u的狀態。

然後題目要求輸出最小的編號。

這裡考慮直接線上段樹上維護。

即id[i]表示節點i所在的區間內的最大值的最小編號。

然後往上pushup的時候應該是可以完全合併的。

另外,求lca可以直接倍增。

注意坑點:當一個點上最大次數為0的時候答案是0,不判斷的話應該會輸出1

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
const int M=maxn*80;
int tot;
int c[M],id[M],lson[M],rson[M],sz[M],T[maxn];
void pushup (int newRoot) {
	c[newRoot]=max(c[lson[newRoot]],c[rson[newRoot]]);
	if (c[lson[newRoot]]==c[newRoot]) id[newRoot]=id[lson[newRoot]];
	else id[newRoot]=id[rson[newRoot]];
	sz[newRoot]=sz[lson[newRoot]]+sz[rson[newRoot]]+1;
}
int up (int i,int l,int r,int p,int v) {
	int newRoot=i;
	if (!newRoot) newRoot=++tot,sz[newRoot]=1;
	if (l==r) {
		c[newRoot]+=v;
		id[newRoot]=l;
		return newRoot;
	}
	int mid=(l+r)>>1;
	if (p<=mid) lson[newRoot]=up(lson[newRoot],l,mid,p,v);
	if (p>mid) rson[newRoot]=up(rson[newRoot],mid+1,r,p,v);
	pushup(newRoot);
	return newRoot;
} 
int merge (int x,int y,int l,int r) {
	//合併根為x和y的線段樹,返回新的根
	if (!x) return y;
	if (!y) return x;
	if (l==r) {
		c[x]+=c[y];
		return x;
	}
	if (sz[x]<sz[y]) swap(x,y);
	int mid=(l+r)>>1;
	lson[x]=merge(lson[x],lson[y],l,mid);
	rson[x]=merge(rson[x],rson[y],mid+1,r);
	pushup(x);
	return x;
}
int n;
vector<int> g[maxn];
int h[maxn],father[25][maxn];
void dfs (int x) {
	for (int y:g[x]) {
		if (y==father[0][x]) continue;
		father[0][y]=x;
		h[y]=h[x]+1;
		dfs(y);
	}
}
int lca (int x,int y) {
	if (h[x]<h[y]) swap(x,y);
	for (int i=20;i>=0;i--) {
		if (h[x]-h[y]>>i) x=father[i][x];
	}
	if (x==y) return x;
	for (int i=20;i>=0;i--) {
		if (father[i][x]!=father[i][y]) {
			x=father[i][x];
			y=father[i][y];
		}
	}
	return father[0][x];
}
int ans[maxn];
void dfs1 (int x) {
	for (int y:g[x]) {
		if (y==father[0][x]) continue;
		dfs1(y);
	}
	int maxson=-1,u=0;
	for (int y:g[x]) {
		if (y==father[0][x]) continue;
		if (sz[T[y]]>maxson) {
			maxson=sz[T[y]];
			u=y;
		}
	}
	if (u) T[x]=merge(T[x],T[u],1,1e5);
	for (int y:g[x]) {
		if (y==father[0][x]) continue;
		if (y==u) continue;
		T[x]=merge(T[x],T[y],1,1e5);
	}
	ans[x]=id[T[x]];
	if (c[T[x]]==0) ans[x]=0;
}
int m;
int main () {
	scanf("%d%d",&n,&m);
	for (int i=1;i<n;i++) {
		int x,y;
		scanf("%d%d",&x,&y);
		g[x].push_back(y);
		g[y].push_back(x);
	}
	dfs(1);
	for (int i=1;i<=20;i++) {
		for (int j=1;j<=n;j++) {
			father[i][j]=father[i-1][father[i-1][j]];
		}
	}
	while (m--) {
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		T[x]=up(T[x],1,1e5,z,1);
		T[y]=up(T[y],1,1e5,z,1);
		T[lca(x,y)]=up(T[lca(x,y)],1,1e5,z,-1);
		T[father[0][lca(x,y)]]=up(T[father[0][lca(x,y)]],1,1e5,z,-1);
	}
	dfs1(1);
	for (int i=1;i<=n;i++) printf("%d\n",ans[i]);
}