比赛 cdcqの省选膜你赛 评测结果 WWWAWWAAAAWWWWWWWWWW
题目名称 秘术「天文密葬法」 最终得分 25
用户昵称 Herrwerner 运行时间 0.902 s
代码语言 C++ 内存使用 13.45 MiB
提交时间 2017-04-11 20:02:52
显示代码纯文本
#include<cstdio>
#include<cmath>

const int len(200000);
const double limt(707070707070.4646464);
int n,m,a[len+10],b[len+10],x,y,all;
struct Node{int nd,nx,root;}bot[len*2+10];int tot,first[len+10];
bool bf,flag[len+10];
double MID,l,r;

void add(int a,int b){bot[++tot]=(Node){b,first[a],0};first[a]=tot;}
template <class T>void umax(T &a,T b){if(a<b)a=b;}
template <class T>void umin(T &a,T b){if(a>b)a=b;}
template <class T> void read(T&x)
{
	x=0;int f=0; char c=getchar();
	while(c<'0'||c>'9'){f=(c=='-');c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
	x=f?-x:x;
} 

namespace Dac
{
	int size[len+10],big[len+10],root[len+10],color[len+10];
	double dis[len+10],Last[len+10],NO;
	void Get_size(int x,int f)
	{
		size[x]=1; big[x]=0;
		for(int v=first[x];v;v=bot[v].nx)
		if(!flag[bot[v].nd] && bot[v].nd!=f)
		{
			Get_size(bot[v].nd,x);
			size[x]+=size[bot[v].nd];
			umax(big[x],size[bot[v].nd]);
		}
	}
	void Get_root(int x,int f)
	{
		color[x]=color[f];
		for(int v=first[x];v;v=bot[v].nx)
		if(!flag[bot[v].nd] && bot[v].nd!=f) Get_root(bot[v].nd,x);
		umax(big[x],all-size[x]);
		if(big[x]*2<=all)root[color[x]]=x;
	}
	void Deal(int x)
	{
		flag[x]=1;
		Get_size(x,0);
		for(int v=first[x];v;v=bot[v].nx)
		if(!flag[bot[v].nd])
		{
			color[x]=bot[v].nd; all=size[bot[v].nd];
			Get_root(bot[v].nd,x);
			bot[v].root=root[bot[v].nd];
		}
		for(int v=first[x];v;v=bot[v].nx)
		if(!flag[bot[v].nd]&&size[bot[v].nd]>=m)Deal(bot[v].root);
	}
	void Back()
	{
		for(int i=1;i<=m;i++)Last[i]=NO;
		for(int i=1;i<=n;i++)flag[i]=0;
	}
	void Run()
	{
		Get_size(1,0); NO=707070707070.4646464;
		Last[0]=0;
		for(int i=1;i<=m;i++)Last[i]=NO;
		for(int i=1;i<=n;i++)
		{
			umax(big[i],n-size[i]);
			if(big[i]*2<=n)root[0]=i;
		}
		Deal(root[0]);
	}
	void update(int x,int f,int d)
	{
		dis[x]+=a[x]-b[x]*MID;
		if(Last[m-d+1]!=NO&&Last[m-d+1]+dis[x]<0)bf=true;
		if(d==m || bf)return ;
		for(int v=first[x];v;v=bot[v].nx)
		if(!flag[bot[v].nd] && bot[v].nd!=f)
		 dis[bot[v].nd]=dis[x],update(bot[v].nd,x,d+1);
	}
	void update_L(int x,int f,int d)
	{
		umin(Last[d],dis[x]);
		if(d==m || bf)return ;
		for(int v=first[x];v;v=bot[v].nx)
		if(!flag[bot[v].nd] && bot[v].nd!=f)update_L(bot[v].nd,x,d+1);
	}
	void dfs(int x)
	{
		flag[x]=1; Last[1]=0;
		for(int v=first[x];v;v=bot[v].nx)
		if(!flag[bot[v].nd])
		{
			dis[bot[v].nd]=a[x]-b[x]*MID;
			update(bot[v].nd,x,2);
			if(bf)break;
			update_L(bot[v].nd,x,2);
		}
		for(int i=1;i<=size[x]&&i<=m;i++)Last[i]=NO;
		if(bf)return;
		for(int v=first[x];v;v=bot[v].nx)
		if(!flag[bot[v].nd]&&size[bot[v].nd]>=m)dfs(bot[v].root);
	}
}

namespace ONE
{
	void Run()	
	{
		Dac::Run();
		for(l=0,r=limt;r-l>1e-3;)
		{
			MID=(l+r)/2; bf=false; 
			Dac::Back();
			Dac::dfs(Dac::root[0]);
			(bf)?r=MID:l=MID;
		}
		r=r*100;
		printf("%.2f",round(r)/100);
	}
}

namespace TWO
{
	void Run()
	{
		double r=0;
		for(int i=1;i<=n;i++)umax(r,1.0*a[i]/b[i]);
		printf("%.2f",round(r)/100);		
	}
}

int main()
{
	freopen("cdcq_b.in","r",stdin);
	freopen("cdcq_b.out","w",stdout);
	read(n);read(m);
	for(int i=1;i<=n;i++)read(a[i]);
	for(int i=1;i<=n;i++)read(b[i]);
	for(int i=1;i<n;i++)read(x),read(y),add(x,y),add(y,x);
	(m!=-1)?ONE::Run():TWO::Run();
	return 0;
}