首页 > 其他 > 详细

Luogu P3576 [POI2014]MRO-Ant colony

时间:2020-08-27 20:43:38      阅读:62      评论:0      收藏:0      [点我收藏+]

题面

由于蚂蚁没有办法走回头路(概率DP),所以答案是唯一的,并有点像树形DP

正难则反,观察到每群蚂蚁的终点是一定的,可以从终点DP

由整除的性质可以发现,每个点能被食蚁兽吃掉的蚂蚁数是一个区间

所以DP维护每个叶子节点的答案区间,二分统计蚂蚁群数

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int N=1e6+5;
int cnt,to[N<<1],nxt[N<<1],he[N],R[N],L[N],son[N],a[N],n,m,k;
ll ans;

inline void add(int u,int v) {
	to[++cnt]=v,nxt[cnt]=he[u],he[u]=cnt;
}

inline void dp(int u,int siz,int l,int r) {
	if((ll)siz*l>a[m]) return;
	L[u]=siz*l;
	if((ll)siz*(r+1)-1>a[m]) R[u]=a[m];
		else R[u]=siz*(r+1)-1;
}

void dfs(int fa,int u) {
	for(int e=he[u];e;e=nxt[e]) {
		int v=to[e];
		if(v!=fa) {
			dp(v,(son[v]==0?1:son[v]),L[u],R[u]);
			if(L[v]!=0||R[v]!=0) {
				dfs(u,v);
			} 
		}
	}
}


inline int left(int x) {
	int l=1,r=m,ans;
	while(l<=r) {
		int mid=l+r>>1;
		if(a[mid]>=x) ans=mid,r=mid-1;
			else l=mid+1;  
	}
	return ans;
}

inline int right(int x) {
	int l=1,r=m,ans=0;
	while(l<=r) {
		int mid=l+r>>1;
		if(a[mid]<=x) ans=mid,l=mid+1;
			else r=mid-1;
	}
	return ans;
}

int main() {
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1;i<=m;i++) {
		scanf("%d",&a[i]);
	}
	sort(a+1,a+m+1);
	int rt=0,Fa=0;
	for(int i=1;i<n;i++) {
		int u,v; scanf("%d%d",&u,&v);
		add(u,v),add(v,u);
		son[u]++,son[v]++;
		if(i==1) {
			rt=u,Fa=v;
		}
	}
	for(int i=1;i<=n;i++) son[i]--;
	dp(rt,(son[rt]==0?1:son[rt]),k,k);
	dp(Fa,(son[Fa]==0?1:son[Fa]),k,k);
	dfs(Fa,rt),dfs(rt,Fa);
	for(int i=1;i<=n;i++) {
	//	if(!son[i]) printf("%d %d\n",L[i],R[i]);
		if(!son[i]&&(L[i]||R[i])) {
			ans+=right(R[i])-left(L[i])+1;
		}
	}
	printf("%lld\n",ans*k);
	return 0;
} 

  

 

Luogu P3576 [POI2014]MRO-Ant colony

原文:https://www.cnblogs.com/wsfwsf/p/13573286.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!