首页 > 其他分享 >P8290 [省选联考 2022] 填树

P8290 [省选联考 2022] 填树

时间:2024-04-16 20:47:29浏览次数:16  
标签:P8290 Madd 210 省选 ans2 int mathcal 联考 DP

My Blogs

P8290 [省选联考 2022] 填树

很有意思的拉插优化 DP。

首先可以枚举 \(L\) 来限制选的数的值域在 \(L,L+k\) 中。然后进行树上 DP:设 \(v_i\) 表示当前点 \(i\) 能填多少种数,\(w_i\) 表示当前点 \(i\) 能填的数的和。

\(f_i\) 表示当前 \(i\) 子树内的所有合法根链数量,\(g_i\) 表示 \(i\) 子树内所有根链的权值之和。假设在合并子树 \(to\),转移方程:

\[\begin{aligned} v_i&=\max(0,\min(r_i,L+k)-\max(l_i,L)+1)\\ w_i&=\max(0,\frac{(\min(r_i,L+k)+\max(l_i,L))v_i}2)\\ ans1&\rightarrow ans1+f_if_{to}\\ ans2&\rightarrow ans2+f_ig_{to}+f_{to}g_i\\ f_i&\rightarrow f_i+v_if_{to}\\ g_i&\rightarrow g_i+v_ig_{to}+f_{to}w_i \end{aligned} \]

但是这样会算重,比如一个最小值为 \(3\),最大值为 \(5\) 的方案,在 \(k=3\) 的时候会被算两次(\(L=2,R=5\) 时被算一次,\(L=3,R=6\) 时被算一次)。可以在 DP 中多开一维记录最小值是否取到了 \(L\),但是略显繁琐,常数也并不优秀。

所以考虑容斥,算 \(2V\) 遍,每次用 \((L,L+k)\) 的答案减去 \((L+1,L+k)\) 的答案,这样得到的就是最小值恰好为 \(L\) 的答案。

一次 DP 复杂度是 \(\mathcal O(n)\),总复杂度 \(\mathcal O(nV)\)。但是还不够。

观察 \(ans1\) 和 \(ans2\),如果用分段法把 \(\min\) 和 \(\max\) 拆开,则他们在同一段下一定都是关于 \(V\) 的不超过 \(n+1\) 次的多项式。

对于 \(ans1\),其是由若干个 \(v\) 乘起来的,而 \(v\) 要么是常数,要么是关于 \(L\) 的单项式,所以次数不会超过 \(n\)。

对于 \(ans2\),是由一个 \(w\) 和多个 \(v\) 乘起来的,而 \(w\) 可能是一个关于 \(L\) 的二次多项式,所以最高次数是 \(n+1\)。下面只考虑处理 \(ans2\),\(ans1\) 同理。

这样考虑设一个连续段 \(l,r\),设 \(ans_i\) 为 \(L=i+l-1\) 时的 \(ans2\)。有结论:把 \(ans_i\) 做一遍前缀和,得到的 \(ans_i\) 是关于 \(L\) 的不超过 \(n+2\) 次的多项式。

考虑设 \(F(x)=\sum_{i=0}^na_ix^i\),则做一遍前缀和之后 \(S'(x)=\sum_{i=0}^na_i\sum_{j=1}^xx^j\),最高次项是一个 \(n+1\) 次的自然数幂和,所以得到的前缀和最高次不超过 \(n+2\)。

所以可以只求 \(n+3\) 个点值,用拉插公式求出在 \(L=r\) 时前缀和的点值。连续段个数是 \(\mathcal O(n)\) 的,每次需要做 \(\mathcal O(n)\) 次 DP(来确定前 \(n+3\) 个点值),每次 DP 复杂度是 \(\mathcal O(n)\),拉插复杂度不是瓶颈,总复杂度 \(\mathcal O(n^3)\)。注意常数优化。

另一种做法:可以考虑枚举了连续段之后不暴力拉插,而是 DP 的时候直接多项式。因为次数不会超过 \(siz_i\),所以暴力做复杂度是树上背包的 \(\mathcal O(n^2)\)。然后得到了一个 \(\mathcal O(n)\) 次的多项式,想办法求出它的前缀和应该也能做,但是感觉不如拉插简洁和直接。

int n,m,ans1,ans2,sum1,sum2,cnt,len,L,R,v[210],v2[210],fr[210];
int a[210],b[210],f[210],g[210],head[210],to[210],nex[210],numa[810];
vi T[210];
inline void add(int x,int y){to[++cnt]=y,nex[cnt]=head[x],head[x]=cnt;}
void dfs0(int x,int fa){for(auto to:T[x])if(to!=fa)add(x,to),dfs0(to,x);}
void dfs(int x)
{
	int v1=0,v2=0;
	if(min(R,b[x])<max(L,a[x]))f[x]=g[x]=0;
	else
	f[x]=v1=max(0,min(R,b[x])-max(L,a[x])+1),
	g[x]=v2=Cmul(min(R,b[x])+max(L,a[x]),f[x],(MOD+1)>>1);
	Madd(sum1,f[x]),Madd(sum2,g[x]);
	for(int i=head[x];i;i=nex[i])
	{
		dfs(to[i]);
		if(!v1)continue;
		Madd(sum1,Cmul(f[x],f[to[i]])),Madd(sum2,Cmul(f[x],g[to[i]]),Cmul(g[x],f[to[i]]));
		Madd(g[x],Cadd(Cmul(f[to[i]],v2),Cmul(v1,g[to[i]]))),Madd(f[x],Cmul(v1,f[to[i]]));
	}
}
inline void mian()
{
	read(n,m),fr[0]=1;int x,y,rr=-inf;L=inf;
	for(int i=1;i<=204;++i)fr[i]=Cmul(fr[i-1],i);
	for(int i=1;i<=n;++i)read(a[i],b[i]),Mmin(L,a[i]),Mmax(rr,b[i]);
	for(int i=1;i<n;++i)read(x,y),T[x].eb(y),T[y].eb(x);
	dfs0(1,0),R=L+m-1;
	for(int i=1;i<=n;++i)numa[++len]=a[i],numa[++len]=b[i]-m+1,numa[++len]=b[i]+1,numa[++len]=a[i]-m;
	sort(numa+1,numa+1+len),len=unique(numa+1,numa+1+len)-numa-1;
	for(int i=1;i<len;++i)
	{
		if(numa[i+1]-numa[i]<=n+3)
		{
			L=numa[i],R=L+m;
			while(L<numa[i+1])sum1=sum2=0,dfs(1),Madd(ans1,sum1),Madd(ans2,sum2),++L,++R;
			continue;
		}
		for(int j=1;j<=n+3;++j)
		{
			L=numa[i]-1+j,R=numa[i]-1+j+m,sum1=sum2=0,dfs(1);
			v[j]=Cadd(v[j-1],sum1),v2[j]=Cadd(v2[j-1],sum2);
		}
		int tmp=1,X=numa[i+1]-1;
		for(int j=1;j<=n+3;++j)Mmul(tmp,X-(numa[i]+j-1));
		for(int j=1;j<=n+3;++j)
		{
			int va=fr[j-1];
			if((n+3-j)&1)Mmul(va,Cdel(0,fr[n+3-j]));
			else Mmul(va,fr[n+3-j]);
			Madd(ans1,Cmul(v[j],tmp,power(Cmul(va,X-(numa[i]+j-1)),MOD-2)));
			Madd(ans2,Cmul(v2[j],tmp,power(Cmul(va,X-(numa[i]+j-1)),MOD-2)));
		}
	}
	--m;
	for(int i=1;i<len;++i)
	{
		if(numa[i+1]-numa[i]<=n+3)
		{
			L=numa[i],R=L+m;
			while(L<numa[i+1])sum1=sum2=0,dfs(1),Mdel(ans1,sum1),Mdel(ans2,sum2),++L,++R;
			continue;
		}
		for(int j=1;j<=n+3;++j)
		{
			L=numa[i]-1+j,R=numa[i]-1+j+m,sum1=sum2=0,dfs(1);
			v[j]=Cadd(v[j-1],sum1),v2[j]=Cadd(v2[j-1],sum2);
		}
		int tmp=1,X=numa[i+1]-1;
		for(int j=1;j<=n+3;++j)Mmul(tmp,X-(numa[i]+j-1));
		for(int j=1;j<=n+3;++j)
		{
			int va=fr[j-1];
			if((n+3-j)&1)Mmul(va,Cdel(0,fr[n+3-j]));
			else Mmul(va,fr[n+3-j]);
			Mdel(ans1,Cmul(v[j],tmp,power(Cmul(va,X-(numa[i]+j-1)),MOD-2)));
			Mdel(ans2,Cmul(v2[j],tmp,power(Cmul(va,X-(numa[i]+j-1)),MOD-2)));
		}
	}
	write(ans1,'\n',ans2);
}

标签:P8290,Madd,210,省选,ans2,int,mathcal,联考,DP
From: https://www.cnblogs.com/WrongAnswer90/p/18139126

相关文章

  • 2024/04/05 多校集训B层-省选模拟5
    T1魔法题面有\(n\)个小球排成一行,每个小球是红色或者蓝色。开始你被给定了两个非负整数\(R\)和\(B\)。每次你可以施展一个魔法,每次魔法你可以选择任意不同的\(R+B\)个球,将这些球全部变成白色,但是需要满足下列条件:你选择的\(R+B\)个球中,需要有恰好\(R\)个红球......
  • #6912. 「梦熊省选难度挑战赛 2023」奇迹之夜
    #6912.「梦熊省选难度挑战赛2023」奇迹之夜树形dp调的好折磨。距离小于交通范围\(L\)的一定是举办聚会,所以可以预处理出\(g_i\)表示深度小于\(i\)的都开聚会的总人气和。其次可以建聚会时一定也能建日常活动,所以直接\(w_i=\max(w_i,m_i)\),方便转移。对于大于等于\(......
  • P3745 [六省联考 2017] 期末考试
    原题链接题解令\(f(x)\)代表所有课的发布时间都小于等于x时的不愉快值之和,x越小,AB消耗越大,x越大,C消耗越大,所以感性的想象\(f(x)\)是一个下凹函数然后就可以快乐三分了code#definellunsignedlonglong#include<bits/stdc++.h>usingnamespacestd;inlinevoidread......
  • 2024联合省选游记
    2024联合省选游记省选是\(3/2\)到\(3/3\),笔者写这篇文章的时候已经是三月底了,愚人节比赛刚结束没多久。为什么拖了这么久呢?初三的生活太过忙碌,让人失去了反思与字自省的意识。听我的教练说,优秀的\(OI\)选手都是有规划的,他们知道自己的水平,以及奋斗的方向。就像长途旅行前的......
  • 3.31 联考
    3.31补题A\(5pts\)\(n=2\)时,\(\fracn2=1\),即为nim游戏。\(30pts\)对于\((a_1,a_2,a_3,a_4,a_5,a_6)\)这样的六元组,至多有\(10^6\)个。记忆化搜索他们的SG值即可。可能需要若干剪枝,因为复杂度其实是\(10^6\times6^3\)的。\(100pts\)首先观察样例2,合理猜测......
  • 管理类联考–复试–管理类知识–口诀
    口诀管理活动尝试汇成一句:紫色的二重性。西施(在门口)(微)笑(迎)人,下馆子时,鸡汁会调制好。人(下定)决心,人(只求)钙剂,原来(是会被)西施笑人,(人)下馆子时,鸡汁会调制好。管理的二重性:自然生产很必要;社会关系是目的;/紫色【自然、社会属性】管理者的角色:三大类角色――人信决,人决心(人际角色:......
  • [省选联考 2024] 重塑时光
    [省选联考2024]重塑时光因为太弱了而感觉网上过的题解都不够详细清晰!所以写了篇题解!估计也会成为我后面给初中的学弟学妹们讲题的题目之一,前提是没有其他人要选它首先,肯定要将概率转为方案数若我们已经将一个排列划分成了\(k+1\)块(有空的)且已经重新拼接成了一条新的时间线......
  • YC262B [ 20240321 CQYC省选模拟赛 T2 ] 倒水(water)
    题意一面墙上有\(n\)个平台,每个平台是一条连接\((h_i,l_i)\)与\((h_i,r_i)\)的线段。其中\(l_i,r_i\)组成一个\([1,2n]\)的排列。你需要按照某种顺序淹没这些平台,每淹没一个平台,水会顺着线段的两个端点垂直下落。假设每次淹没的水是无限的,若当前的平台没有水,则......
  • 联合省选 2024 题解
    魔法手杖考虑判定答案是否可以大于等于\(t\)。观察\(a_i\oplusx<t\)的情况,可以发现满足要求的\(x\)分为若干段:最高\(u\)位为\(a_i\oplust\)的最高\(u\)位;接下来这一位\(t\)为\(1\),且\(x\)取值为\(a_i\)这一位的取值;更低的位随意。这事实上相当于:我们往0......
  • YC263A [ 20240324 CQYC省选模拟赛 T1 ] 光晕 (halation)
    题意给定一个数组\(a\),每次进行以下操作。选择一个\(1\lex\len\),将\(a_x:=(a_x-2^{c_x})\times2\),然后\(c_x:=c_x+1\)如果通过这个操作使得\(a\)严格递增,则\(a\)是好的。你希望找到一个长度为\(n\)的好的数组,使得\(\suma_i\)最小,且她的字典序......