社区讨论

求为何我的代码会随机TLE

P6329【模板】点分树 / 震波参与者 2已保存回复 1

讨论操作

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

当前回复
1 条
当前快照
1 份
快照标识符
@lwj1vmyx
此快照首次捕获于
2024/05/23 17:28
2 年前
此快照最后确认于
2024/05/23 20:19
2 年前
查看原帖
如下代码可以得到很多种不同的分数。
CPP
/*
	Luogu name: Symbolize
	Luogu uid: 672793
*/
#include<bits/stdc++.h>
//#define int long long
#define pii pair<int,int>
#define x first
#define y second
#define rep1(i,l,r) for(register int i=l;i<=r;++i)
#define rep2(i,l,r) for(register int i=l;i>=r;--i)
#define rep3(i,x,y,z) for(register int i=x[y];~i;i=z[i])
#define rep4(i,x) for(auto i:x)
#define debug() puts("----------")
const int N=1e5+10;
const int M=5e6+10;
const int inf=0x3f3f3f3f3f3f3f3f;
using namespace std;
int n,m,a[N],h[N],e[N<<1],ne[N<<1],idx,last,sz[N],Max[N],root,siz,Fa[N],dep[N],f[N][21];
bool vis[N];
struct Segment_Tree
{
	int root[N],idx;
	struct node
	{
		int l,r;
		int sum;
	}tr[M];
	void push_up(int p){tr[p].sum=tr[tr[p].l].sum+tr[tr[p].r].sum;}
	void update(int &p,int l,int r,int x,int k)
	{
		if(!p) p=++idx;
		if(l==r)
		{
			tr[p].sum+=k;
			return;
		}
		int mid=l+r>>1;
		if(x<=mid) update(tr[p].l,l,mid,x,k);
		else update(tr[p].r,mid+1,r,x,k);
		push_up(p);
		return;
	}
	int query(int p,int l,int r,int pl,int pr)
	{
		int ans=0;
		if(!p) return 0;
		if(pl<=l&&pr>=r) return tr[p].sum;
		int mid=l+r>>1;
		if(pl<=mid) ans+=query(tr[p].l,l,mid,pl,pr);
		if(pr>mid) ans+=query(tr[p].r,mid+1,r,pl,pr);
		return ans;
	}
}seg1,seg2;
int read()
{
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return f*x;
}
void add(int x,int y)
{
	e[idx]=y;
	ne[idx]=h[x];
	h[x]=idx++;
	return;
}
void Dfs(int x,int fa)
{
	f[x][0]=fa;
	dep[x]=dep[fa]+1;
	rep3(i,h,x,ne)
	{
		int to=e[i];
		if(to==fa) continue;
		Dfs(to,x);
	}
	return;
}
void init()
{
	rep1(j,1,20) rep1(i,1,n) f[i][j]=f[f[i][j-1]][j-1];
	return;
}
void plc(int &x,int k)
{
	int kase=0;
	while(k)
	{
		if(k&1) x=f[x][kase];
		++kase;
		k>>=1;
	}
	return;
}
int LCA(int x,int y)
{
	if(dep[x]<dep[y]) swap(x,y);
	plc(x,dep[x]-dep[y]);
	if(x==y) return x;
	rep2(i,20,0)
	{
		if(f[x][i]!=f[y][i])
		{
			x=f[x][i];
			y=f[y][i];
		}
	}
	return f[x][0];
}
void find_root(int x,int fa)
{
	sz[x]=1;
	Max[x]=0;
	rep3(i,h,x,ne)
	{
		int to=e[i];
		if(to==fa||vis[to]) continue;
		find_root(to,x);
		sz[x]+=sz[to];
		Max[x]=max(Max[x],sz[to]);
	}
	Max[x]=max(Max[x],siz-sz[x]);
	if(Max[x]<Max[root]) root=x;
	return;
}
void dfs(int x)
{
	vis[x]=1;
	rep3(i,h,x,ne)
	{
		int to=e[i];
		if(vis[to]) continue;
		Max[0]=inf;
		root=0;
		siz=sz[to];
		find_root(to,0);
		Fa[root]=x;
		dfs(root);
	} 
	return;
}
int getdist(int x,int y){return dep[x]+dep[y]-2*dep[LCA(x,y)];}
void update(int x,int k)
{
	int now=x;
	while(now)
	{
		seg1.update(seg1.root[now],0,n-1,getdist(x,now),k);
		if(Fa[now]) seg2.update(seg2.root[now],0,n-1,getdist(x,Fa[now]),k);
		now=Fa[now];
	}
	return;
}
int query(int x,int k)
{
	int now=x,son=0,ans=0;
	while(now)
	{
		if(getdist(x,now)<=k)
		{
			ans+=seg1.query(seg1.root[now],0,n-1,0,k-getdist(x,now));
			if(son) ans-=seg2.query(seg2.root[son],0,n-1,0,k-getdist(x,now));
		}
		son=now;
		now=Fa[now];
	}
	return ans;
}
signed main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	memset(h,-1,sizeof h);
	n=read();
	m=read();
	rep1(i,1,n) a[i]=read();
	rep1(i,1,n-1)
	{
		int u=read();
		int v=read();
		add(u,v);
		add(v,u);
	}
	Dfs(1,0);
	init();
	Max[0]=inf;
	root=0;
	siz=n;
	find_root(1,0);
	dfs(root);
	rep1(i,1,n) update(i,a[i]);
	while(m--)
	{
		int opt=read();
		int x=read()^last;
		int k=read()^last;
		if(opt==0)
		{
			last=query(x,k);
			cout<<last<<endl;
		}
		if(opt==1)
		{
			update(x,k-a[x]);
			a[x]=k;
		}
	}
	return 0;
}

eg:1|2|3

回复

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

正在加载回复...