震惊,洛谷竟公然卡常!!!
查看原帖
震惊,洛谷竟公然卡常!!!
141572
JCY_楼主2020/1/12 11:49
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
#define ms(a,b) memset(a,b,sizeof a)
#define sz(a) (int)a.size()
#define maxx(a,b) a=max(a,b)
#define minx(a,b) a=min(a,b)
#define endl '\n'
const int maxn=3e5+5,maxedge=3e5+5,maxnum=3e5+5,inf=0x3f3f3f3f,mod=1e9+7;
struct edge
{
	int v,w,nxt;
} e[maxedge<<1];
int n,head[maxn],tot,num,dep[maxn],cnt=0,a[maxn<<1],first[maxn],mn[maxn<<1][21],lg2[maxn<<1],dist[maxn],sum[maxn],rec[maxn],ans;
pii ques[maxnum];
inline void clear_graph()
{
	ms(head,-1);
	tot=0;
}
inline void add_edge(int u,int v,int w)
{
	e[tot].v=v;
	e[tot].w=w;
	e[tot].nxt=head[u];
	head[u]=tot++;
}
void init()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	// freopen("draft.in","r",stdin);
	// freopen("draft.out","w",stdout);
	clear_graph();
	lg2[1]=0;
	for(int i=2;i<maxn<<1;i++)
		lg2[i]=i&i-1 ? lg2[i-1]:lg2[i-1]+1;
}
void dfs(int u,int pre)
{
	dep[u]=dep[pre]+1;
	a[++cnt]=u;
	first[u]=cnt;
	for(int i=head[u];~i;i=e[i].nxt)
	{
		if(e[i].v==pre) continue;
		dist[e[i].v]=dist[u]+e[i].w;
		dfs(e[i].v,u);
		a[++cnt]=u;
	}
}
void rmq()
{
	for(int i=1;i<maxn<<1;i++)
		mn[i][0]=a[i];
	for(int j=1;j<=20;j++)
		for(int i=1;i+(1<<j)<=maxn<<1;i++)
		{
			int x=mn[i][j-1],y=mn[i+(1<<j-1)][j-1];
			mn[i][j]=dep[x]<dep[y] ? x:y;
		}
}
int lca(int x,int y)
{
	int l=first[x],r=first[y];
	if(l>r) swap(l,r);
	int k=lg2[r-l+1];
	x=mn[l][k],y=mn[r-(1<<k)+1][k];
	return dep[x]<dep[y] ? x:y;
}
void dfs2(int u,int pre)
{
	for(int i=head[u];~i;i=e[i].nxt)
	{
		if(e[i].v==pre) continue;
		rec[e[i].v]=e[i].w;
		dfs2(e[i].v,u);
		sum[u]+=sum[e[i].v];
	}
}
bool check(int lmt)
{
	ms(sum,0);
	int maxi=-inf,s=0,maxi2=-inf;
	for(int i=1;i<=num;i++)
	{
		int t=lca(ques[i].first,ques[i].second);
		int k=dist[ques[i].first]+dist[ques[i].second]-2*dist[t];
		if(k<=lmt) continue;
		sum[ques[i].first]++;
		sum[ques[i].second]++;
		sum[t]-=2;
		s++;
		maxx(maxi,k);
	}
	if(maxi<=-inf) return true;
	dfs2(1,0);
	for(int i=2;i<=n;i++)
		if(sum[i]>=s) maxx(maxi2,rec[i]);
	if(maxi2<=-inf) return false;
	return maxi-maxi2<=lmt;
}
int main()
{
	init();
	cin>>n>>num;
	for(int i=1;i<n;i++)
	{
		int u,v,w;
		cin>>u>>v>>w;
		add_edge(u,v,w);
		add_edge(v,u,w);
	}
	dfs(1,0);
	rmq();
	for(int i=1;i<=num;i++)
		cin>>ques[i].first>>ques[i].second;
	int l=0,r=3e8;
	while(l<=r)
	{
		int mid=l+r>>1;
		if(check(mid))
		{
			ans=mid;
			r=mid-1;
		}
		else l=mid+1;
	}
	cout<<ans<<endl;
	return EXIT_SUCCESS;
}

将第59行“<=20”改为“<21”
TLE(95)->AC

2020/1/12 11:49
加载中...