社区讨论

90分求助,#4 TLE……

P3258[JLOI2014] 松鼠的新家参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@lo965tnr
此快照首次捕获于
2023/10/28 06:12
2 年前
此快照最后确认于
2023/10/28 06:12
2 年前
查看原帖
大佬帮忙优化一下,谢谢!

CODE:

CPP
#include<bits/stdc++.h>
#define ls k<<1
#define rs k<<1|1
#define mid (l+r>>1)
using namespace std;
const int maxN=3e5+9;
int n,m,a[maxN];
int fa[maxN],sz[maxN],sn[maxN],dep[maxN];
int dfn[maxN],rnk[maxN],top[maxN],cnt;
int tree[maxN<<2],lazy[maxN<<2];
vector<int>e[maxN];
int read(){
	int s=0,f=1;
	char ch=getchar();
	while (!isdigit(ch)){
		ch=='-'?f=-1:f=1;
		ch=getchar();
	}
	while (isdigit(ch)){
		s=(s<<3)+(s<<1)+(ch^48);
		ch=getchar();
	}
	return s*f;
}
void write(int x){
	(x<0)?(putchar('-'),x=-x):-1;
	if (x>9) write(x/10);
	putchar(x%10+'0');
}
void pushup(int k){tree[k]=tree[ls]+tree[rs];}
void pushdown(int k,int l,int r){
	tree[ls]+=(mid-l+1)*lazy[k];
	tree[rs]+=(r-mid)*lazy[k];
	lazy[ls]+=lazy[k];
	lazy[rs]+=lazy[k];
	lazy[k]=0;
}
void update(int k,int l,int r,int x,int y,int v){
	if (x>r||y<l) return;
	if (l>=x&&r<=y){
		tree[k]+=(r-l+1)*v;
		lazy[k]+=v;
		return;
	}
	pushdown(k,l,r);
	update(ls,l,mid,x,y,v);
	update(rs,mid+1,r,x,y,v);
	pushup(k);
}
int query(int k,int l,int r,int x,int y){
	if (x>r||y<l) return 0;
	if (l>=x&&r<=y) return tree[k];
	pushdown(k,l,r);
	return query(ls,l,mid,x,y)+query(rs,mid+1,r,x,y);
}
void dfs1(int u,int pre){
	sz[u]=1;
	for (register int i(0);i<e[u].size();++i){
		int v=e[u][i];
		if (v==pre) continue;
		dep[v]=dep[u]+1;
		fa[v]=u;
		dfs1(v,u);
		sz[u]+=sz[v];
		sz[v]>sz[sn[u]]?sn[u]=v:-1;
	}
}
void dfs2(int u,int t){
	top[u]=t;
	dfn[u]=++cnt;
	rnk[cnt]=u;
	if (sn[u]) dfs2(sn[u],t);
	for (register int i(0);i<e[u].size();++i){
		int v=e[u][i];
		if (v==fa[u]||v==sn[u]) continue;
		dfs2(v,v);
	}
}
void update_chain(int x,int y,int v){
	int fx=top[x],fy=top[y];
	while (fx!=fy){
		if (dep[fx]<dep[fy]) swap(x,y),swap(fx,fy);
		update(1,1,n,dfn[fx],dfn[x],v);
		x=fa[fx],fx=top[x];
	}
	if (dfn[x]>dfn[y]) swap(x,y);
	update(1,1,n,dfn[x],dfn[y],v);
}
int main(){
	n=read();
	for (register int i(1);i<=n;++i) a[i]=read();
	for (register int i(1);i<n;++i){
		int x=read(),y=read();
		e[x].push_back(y),e[y].push_back(x);
	}
	dfs1(a[1],0),dfs2(a[1],a[1]);
	for (register int i(2);i<=n;++i) update_chain(a[i-1],a[i],1);
	for (register int i(2);i<=n;++i) update(1,1,n,dfn[a[i]],dfn[a[i]],-1);
	for (register int i(1);i<=n;++i) write(query(1,1,n,dfn[i],dfn[i])),puts("");
	return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...