树剖代码求助
查看原帖
树剖代码求助
145355
wsyhb楼主2020/9/2 22:01

这是一道树剖板题,只 AC#1#2 以及 Hack 数据,其他都 TLE 掉了。下载了 #3 数据,发现 n=m=6000n=m=6000,本机却跑了 4s,答案正确,看来是时间复杂度写假了,却不知道是哪里的问题,请 dalao 帮忙看看代码,谢谢!

#include<bits/stdc++.h>
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)<(b)?(b):(a))
using namespace std;
const int buffer_size=1e5+5;
char buf[buffer_size],*S,*T;
inline char read_char()
{
    if(S==T) T=(S=buf)+fread(buf,1,buffer_size,stdin);
    return S!=T?*(S++):EOF;
}
inline int read_int()
{
    bool flag=false;
    char c=read_char();
    while(c<'0'||c>'9')
    {
        flag=(c=='-'?true:flag);
        c=read_char();
    }
    int x=0;
    while(c>='0'&&c<='9')
    {
        x=(x<<3)+(x<<1)+(c-'0');
        c=read_char();
    }
    return flag?-x:x;
}
inline void read_string(char *s)
{
	char c=read_char();
	while(c<'A'||c>'Z') c=read_char();
	while(c>='A'&&c<='Z')
	{
		*(s++)=c;
		c=read_char(); 
	}
}
int n,m;
const int V=2e5+5;
const int E=4e5+5;
int End[E],Last[V],Next[E],Len[E],e=1;
inline void add_edge(int x,int y,int z)
{
	End[++e]=y;
	Next[e]=Last[x];
	Last[x]=e;
	Len[e]=z;
	End[++e]=x;
	Next[e]=Last[y];
	Last[y]=e;
	Len[e]=z;
}
int dep[V],size[V],fath[V],son[V];
void dfs1(int x,int fa)
{
	dep[x]=dep[fa]+1;
	size[x]=1;
	fath[x]=fa;
	son[x]=-1;
	int max_size=0;
	for(int i=Last[x];i;i=Next[i])
	{
		int y=End[i];
		if(y!=fa)
		{
			dfs1(y,x);
			size[x]+=size[y];
			if(size[y]>max_size)
			{
				max_size=size[y];
				son[x]=y;
			}
		}
	}
}
int top[V],id[V],old[V],t;
void dfs2(int x,int top_now)
{
	id[x]=++t;
	old[t]=x;
	top[x]=top_now;
	if(son[x]!=-1) dfs2(son[x],top_now);
	for(int i=Last[x];i;i=Next[i])
	{
		int y=End[i];
		if(y!=fath[x]&&y!=son[x]) dfs2(y,y);
	}
}
int w[V],sum[V<<2],Min[V<<2],Max[V<<2],lazy[V<<2];
inline void merge(int k)
{
	sum[k]=sum[k<<1]+sum[k<<1|1];
	Min[k]=min(Min[k<<1],Min[k<<1|1]);
	Max[k]=max(Max[k<<1],Max[k<<1|1]);
}
void build(int k,int l,int r)
{
	if(l==r)
	{
		sum[k]=Min[k]=Max[k]=w[old[l]];
		return;
	}
	int mid=(l+r)>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
	merge(k);
}
inline void Swap(int &x,int &y)
{
	x^=y,y^=x,x^=y;
}
inline void work(int k)
{
	sum[k]=-sum[k];
	Min[k]=-Min[k];
	Max[k]=-Max[k];
	swap(Min[k],Max[k]);
	lazy[k]^=1;
}
inline void push_down(int k)
{
	lazy[k]=0;
	work(k<<1);
	work(k<<1|1);
}
void change(int k,int l,int r,int p,int v)
{
	if(l==r)
	{
		sum[k]=Min[k]=Max[k]=v;
		return;
	}
	if(lazy[k]) push_down(k);
	int mid=(l+r)>>1;
	if(p<=mid) change(k<<1,l,mid,p,v);
	else change(k<<1|1,mid+1,r,p,v);
	merge(k);
}
void modify(int k,int l,int r,int p,int q)
{
	if(p<=l&&r<=q)
	{
		work(k);
		return;
	}
	if(lazy[k]) push_down(k);
	int mid=(l+r)>>1;
	if(p<=mid) modify(k<<1,l,mid,p,q);
	if(q>mid) modify(k<<1|1,mid+1,r,p,q);
	merge(k);
}
int query_sum(int k,int l,int r,int p,int q)
{
	if(p<=l&&r<=q) return sum[k];
	if(lazy[k]) push_down(k);
	int mid=(l+r)>>1,res=0;
	if(p<=mid) res+=query_sum(k<<1,l,mid,p,q);
	if(q>mid) res+=query_sum(k<<1|1,mid+1,r,p,q);
	return res;
}
int query_max(int k,int l,int r,int p,int q)
{
	if(p<=l&&r<=q) return Max[k];
	if(lazy[k]) push_down(k);
	int mid=(l+r)>>1,res=-1e9;
	if(p<=mid) res=max(res,query_max(k<<1,l,mid,p,q));
	if(q>mid) res=max(res,query_max(k<<1|1,mid+1,r,p,q));
	return res;
}
int query_min(int k,int l,int r,int p,int q)
{
	if(p<=l&&r<=q) return Min[k];
	if(lazy[k]) push_down(k);
	int mid=(l+r)>>1,res=1e9;
	if(p<=mid) res=min(res,query_min(k<<1,l,mid,p,q));
	if(q>mid) res=min(res,query_min(k<<1|1,mid+1,r,p,q));
	return res;
}
inline void modify(int x,int y)
{
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]]) Swap(x,y);
		modify(1,1,n,id[top[x]],id[x]);
		x=fath[top[x]];
	}
	if(x==y) return;
	if(dep[x]>dep[y]) Swap(x,y);
	modify(1,1,n,id[x]+1,id[y]);
}
inline void query_sum(int x,int y)
{
	int ans=0;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]]) Swap(x,y);
		ans+=query_sum(1,1,n,id[top[x]],id[x]);
		x=fath[top[x]];
	}
	if(x!=y)
	{
		if(dep[x]>dep[y]) Swap(x,y);
		ans+=query_sum(1,1,n,id[x]+1,id[y]);
	}
	printf("%d\n",ans);
}
inline void query_max(int x,int y)
{
	int ans=-1e9;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]]) Swap(x,y);
		ans=max(ans,query_max(1,1,n,id[top[x]],id[x]));
		x=fath[top[x]];
	}
	if(x!=y)
	{
		if(dep[x]>dep[y]) Swap(x,y);
		ans=max(ans,query_max(1,1,n,id[x]+1,id[y]));
	}
	printf("%d\n",ans);
}
inline void query_min(int x,int y)
{
	int ans=1e9;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]]) Swap(x,y);
		ans=min(ans,query_min(1,1,n,id[top[x]],id[x]));
		x=fath[top[x]];
	}
	if(x!=y)
	{
		if(dep[x]>dep[y]) Swap(x,y);
		ans=min(ans,query_min(1,1,n,id[x]+1,id[y]));
	}
	printf("%d\n",ans);
}
int main()
{
	n=read_int();
	for(int i=1;i<n;++i)
	{
		int u=read_int()+1,v=read_int()+1,w=read_int();
		add_edge(u,v,w);
	}
	dfs1(1,0);
	dfs2(1,1);
	for(int i=1;i<n;++i)
	{
		int x=End[i<<1],y=End[i<<1|1];
		if(fath[y]==x) Swap(x,y);
		w[x]=Len[i<<1];
	}
	build(1,1,n);
	m=read_int();
	for(int i=1;i<=m;++i)
	{
		static char op[5];
		read_string(op);
		if(op[0]=='C')
		{
			int k=read_int(),w=read_int();
			int x=End[k<<1],y=End[k<<1|1];
			if(fath[y]==x) Swap(x,y);
			change(1,1,n,id[x],w);
		}
		else
		{
			int u=read_int()+1,v=read_int()+1;
			if(op[0]=='N') modify(u,v);
			else if(op[0]=='S') query_sum(u,v);
			else if(op[1]=='A') query_max(u,v);
			else query_min(u,v);
		}
	}
	return 0;
}
2020/9/2 22:01
加载中...