TLE求助
查看原帖
TLE求助
98384
chs007楼主2022/7/8 19:28

调了两天,LOJ上通过,洛谷仍然80pts,而且时间貌似没超多少? #1 #7 TLE

应该是卡不过常,开大时限?貌似我At不起

请求大佬看看怎么优化常数Orz

#include<bits/stdc++.h>
using namespace std;
const long long N=200005;
int n,m,L,R;
int h[N],cnt,Mrt,rt,l,p,quee,ques,quee2,ques2;
int depth[N],col[N],siz[N],vis[N],quexb[N],quexb2[N];
long long tmpL[N],tmpv[N],dis[N],que[N],que2[N];
long long dff_judge[N],sam_judge[N];
long long ans=-2000000000;
inline char gc() {
    static char buf[1000],*p1(buf),*p2(buf);
    return p1==p2 && (p2=(p1=buf)+fread(buf,1,1000,stdin),p1==p2)?EOF:*p1++; 
}

inline int read() {
	int x(0),f(1);
	char ch(gc());
	while (ch<'0' || ch>'9') {
		if (ch=='-') f=-f;
		ch=gc();
	}
	while (ch>='0' && ch<='9') {
		x=(x<<3)+(x<<1)+(ch^48);
		ch=gc();
	}
	return x*f;
}
struct LZKAK
{
	long long L,v;
}tmp[N*2];
struct zido
{
	int a,b,c;
}pl[N],kl[N];
bool dk(zido x,zido y)
{
	if(x.b!=y.b) return x.b<y.b;
	return x.c<y.c;
}
struct shenmeshabi
{
	int to,next,v;
}e[N*2];
bool cmp(LZKAK x,LZKAK y)
{
	return x.L<y.L;
}
void add(int a,int b,int c)
{
	e[++cnt]=(shenmeshabi){b,h[a],c};
	h[a]=cnt;
}
void getrt(int now,int fa,int tn)
{
	siz[now]=1;
	int Max=0;
	depth[now]=0;
	for(int i=h[now];i;i=e[i].next)
	{
		if(vis[e[i].to] || e[i].to==fa) continue;
		getrt(e[i].to,now,tn);
		siz[now]+=siz[e[i].to];
		Max=max(Max,siz[e[i].to]);
		depth[now]=max(depth[e[i].to],depth[now]);
	}
	Max=max(Max,tn-siz[now]);
	if(Max<Mrt) Mrt=Max,rt=now;
	depth[now]+=1;
}
void getdis(int now,int fa,int dep,int bf)
{
	if(dep<=R) tmp[++p].L=dep,tmp[p].v=dis[now];
	siz[now]=1;
	for(int i=h[now];i;i=e[i].next)
	{
		if(vis[e[i].to] || e[i].to==fa) continue;
		dis[e[i].to]=dis[now]+(e[i].v!=e[bf].v)*col[e[i].v];
		getdis(e[i].to,now,dep+1,i);
		siz[now]+=siz[e[i].to];
	}
}
void solve(int now,int fa,int tn)
{
	Mrt=N*1000;
	getrt(now,fa,tn);
	vis[rt]=1;
	l=p=0;
	int cs=0;
	long long g=0;
	long long tag=0;
	long long mx=0;
	int ls,rs;
	int jk=0,jl=0,ck=0;
	for(int i=h[rt];i;i=e[i].next)
		pl[++jk]=(zido){i,e[i].v,depth[e[i].to]};
	sort(pl+1,pl+jk+1,dk);
	for(int i=1;i<=jk;i++)
	{
		if(ck!=pl[i].b) 
		{
			jl++;
			kl[jl].b=0;
			ck=pl[i].b;
			kl[jl].a=i;
			kl[jl].c=0;
		}
		kl[jl].b=max(kl[jl].b,pl[i].c);
		kl[jl].c++;
	}
	sort(kl+1,kl+jl+1,dk);
	int i;
	for(int ty=1;ty<=jl;ty++)
	for(int v=kl[ty].a;v<=kl[ty].a+kl[ty].c-1;v++)
	{
		i=pl[v].a;
		if(e[i].v!=cs)
		{
			cs=e[i].v;
			for(int j=tag+1;j<=p;j++)
			{
				int k=tmp[j].L;
				dff_judge[k]=max(dff_judge[k],sam_judge[k]);
				sam_judge[k]=-2000000000;
			}
			tag=p;
		}
		if(vis[e[i].to]) continue;
		dis[e[i].to]=col[e[i].v];
		getdis(e[i].to,rt,1,i);
		if(p!=1 && p!=0)
		{
			sort(tmp+l+1,tmp+p+1,cmp);
			quee=0;
			ques=1;
			quee2=0;
			ques2=1;
			ls=max(g,L-tmp[p].L),rs=max(g,L-tmp[p].L);
			for(int j=p;j>l;j--)
			{
				while(rs<=min(mx,R-tmp[j].L))
				{
					while(quee>=ques && sam_judge[rs]>=que[quee]) quee--;
					while(quee2>=ques2 && dff_judge[rs]>=que2[quee2]) quee2--;
					que[++quee]=sam_judge[rs];
				que2[++quee2]=dff_judge[rs];
					quexb[quee]=rs;
					quexb2[quee2]=rs;
					rs++;
				}
				while(ls<max(g,L-tmp[j].L)) ls++;
				while(quexb[ques]<ls && ques<=quee) ques++;
				while(quexb2[ques2]<ls && ques2<=quee2) ques2++;	if(ques<=quee)ans=max(ans,que[ques]+tmp[j].v-col[cs]);	if(ques2<=quee2)ans=max(ans,que2[ques2]+tmp[j].v);
			}
		}
		for(int j=l+1;j<=p;j++)
		{
			mx=max(mx,tmp[j].L);
			if(tmp[j].L>=L) ans=max(ans,tmp[j].v);
			sam_judge[tmp[j].L]=max(sam_judge[tmp[j].L],tmp[j].v);
		}
		l=p;
	}
	for(int i=1;i<=p;i++)
		dff_judge[tmp[i].L]=sam_judge[tmp[i].L]=-2000000000;
	for(int i=h[rt];i;i=e[i].next)
	{
		if(vis[e[i].to]) continue;
		solve(e[i].to,now,siz[e[i].to]);
	}
}
int main()
{
	n=read(),m=read(),L=read(),R=read();
	for(int i=1;i<=m;i++)
		col[i]=read();
	for(int i=1;i<n;i++)
	{
		int a=read(),b=read(),c=read();
		add(a,b,c);
		add(b,a,c); 
	} 
	for(int i=0;i<=R;i++)
		sam_judge[i]=dff_judge[i]=-2000000000;
	solve(1,0,n);
	cout<<ans;
	return 0;
} 
2022/7/8 19:28
加载中...