社区讨论

求助,关于为何MLE,TLE

P7735[NOI2021] 轻重边参与者 4已保存回复 9

讨论操作

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

当前回复
9 条
当前快照
1 份
快照标识符
@loc310t6
此快照首次捕获于
2023/10/30 07:08
2 年前
此快照最后确认于
2023/11/04 13:10
2 年前
查看原帖
CPP
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1e5+5;
struct edge
{
	int next,to;
}e[N<<1];
struct segment_tree
{
	int lson,rson,sum,tag,l,r;
}t[N<<2];
int T,n,m,ecnt,res,last=0,tot=0;
int in[N],dep[N],fa[N],top[N],son[N];
int size[N],seg[N],rev[N],tac[N][2],cl[N][2];
int read() 
{
	int res,f=1;
	char ch;
	while((ch=getchar())<'0'||ch>'9')
	if(ch=='-')
	f=-1;
	res=ch-48;
	while((ch=getchar())>='0'&&ch<='9')
	res=res*10+ch-48;
	return res*f; 
}
void add(int x,int y)
{
	e[++ecnt].next=in[x];
	e[ecnt].to=y;
	in[x]=ecnt;
}
void build(int k,int l,int r)//线段树 
{
	t[k].l=l;t[k].r=r;
	t[k].lson=t[k].rson=t[k].sum=t[k].tag=0;
	if(l==r)
	return;
	int mid=l+r>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
}
void pushdown(int k)
{
	if(!t[k].tag)
	return;
	t[k<<1].tag=t[k<<1].lson=t[k<<1].rson=t[k].tag;
	t[k<<1].sum=t[k<<1].r-t[k<<1].l;
	t[k<<1|1].tag=t[k<<1|1].lson=t[k<<1|1].rson=t[k].tag;
	t[k<<1|1].sum=t[k<<1|1].r-t[k<<1|1].l;
	t[k].tag=0;
}
void pushup(int k)
{
	t[k].sum=t[k<<1].sum+t[k<<1|1].sum;
	if(t[k<<1|1].lson==t[k<<1].rson&&t[k<<1|1].lson!=0)
	t[k].sum++;
	t[k].lson=t[k<<1].lson;
	t[k].rson=t[k<<1|1].rson;
}
void modify(int k,int l,int r,int v)
{
	if(t[k].l>=l&&t[k].r<=r)
	{
		t[k].lson=t[k].rson=t[k].tag=v;
		t[k].sum=t[k].r-t[k].l;
		return;
	}
	pushdown(k);
	int mid=t[k].l+t[k].r>>1;
	if(l<=mid)
	modify(k<<1,l,r,v);
	if(mid<r)
	modify(k<<1|1,l,r,v);
	pushup(k);
}
int Get(int k,int l,int r)
{
	if(t[k].l>=l&&t[k].r<=r)
	{
		int task=t[k].sum+(t[k].lson==last&&last!=0);
		last=t[k].rson;
		return task;
	}
	pushdown(k);
	int mid=t[k].l+t[k].r>>1,ans=0;
	if(l<=mid)
	ans+=Get(k<<1,l,r);
	if(mid<r)
	ans+=Get(k<<1|1,l,r);
	pushup(k);
	return ans;
}
int getcol(int x,int v)
{
	if(t[x].l==v&&t[x].r==v)
	return t[x].tag;
	pushdown(x);
	int mid=t[x].l+t[x].r>>1;
	if(v<=mid)
	return getcol(x<<1,v);
	else
	return getcol(x<<1|1,v);
}
void dfs1(int u,int f)//树剖 
{
	int i,v;
	size[u]=1;
	dep[u]=dep[f]+1;
	fa[u]=f;son[u]=0;
	for(i=in[u];i;i=e[i].next)
	{
		v=e[i].to;
		if(v==f)
		continue;
		dfs1(v,u);
		size[u]+=size[v];
		if(size[v]>size[son[u]])
		son[u]=v;
	}
}
void dfs2(int u,int f)
{
	int i,v;
	seg[u]=++res;
	rev[res]=u;
	top[u]=f;
	if(son[u])
	dfs2(son[u],f);
	for(i=in[u];i;i=e[i].next)
	{
		v=e[i].to;
		if(v==fa[u]||v==son[u])
		continue;
		dfs2(v,v);
	}
}
void update(int x,int y,int v)
{
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])
		swap(x,y);
		modify(1,seg[top[x]],seg[x],v);
		x=fa[top[x]];
	}
	modify(1,min(seg[x],seg[y]),max(seg[x],seg[y]),v);
}
void getr(int x,int y)
{
	tot=0;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])
		swap(x,y);
		tac[++tot][0]=seg[top[x]];
		tac[tot][1]=seg[x];
		x=fa[top[x]];
	}
	int i,j,ans=0,task;
	tac[++tot][1]=max(seg[x],seg[y]);
	tac[tot][0]=min(seg[x],seg[y]);
	for(i=1;i<=tot;i++)
	{
		last=0;
		task=Get(1,tac[i][0],tac[i][1]);
		ans+=task;
	}
	for(i=1;i<=tot;i++)
	{
		cl[i][0]=getcol(1,tac[i][0]);
		cl[i][1]=getcol(1,tac[i][1]);
	}
	for(i=1;i<=tot;i++)
	{
		for(j=1;j<=tot;j++)
		{
			if(i==j)
			continue;
			if(fa[rev[tac[j][0]]]==rev[tac[i][1]])
			{
				ans+=(cl[j][0]==cl[i][1]&&cl[j][0]!=0);
				continue;
			}
			if(fa[rev[tac[j][0]]]==rev[tac[i][0]])
			ans+=(cl[j][0]==cl[i][0]&&cl[j][0]!=0);
		}
	}
	printf("%d\n",ans);
}
int main()
{
	int i,x,y,op;
	T=read();
	while(T--)
	{
		ecnt=0;res=0;tot=0;
		n=read();m=read();
		for(i=1;i<=n-1;i++)
		{
			x=read();y=read();
			add(x,y);add(y,x);
		}
		dfs1(1,0);dfs2(1,1);build(1,1,n);
		for(i=1;i<=m;i++)
		{
			op=read();x=read();y=read();
			if(op==1)
			update(x,y,i);
			else
			getr(x,y);
		}
	}
	return 0;
} 
```cpp

回复

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

正在加载回复...