调了两天,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;
}