ZLOJ练习36

written on 2022-07-08

许多题都作为原题形式做过一模一样的,但竟然没有做出来!一道点分治,一道线段树合并,都很模板,真的很不应该!

\(A\)区间dp,虽然过了,但是状态设计得不好,可以直接看看代码回忆一下。

然后根据C题总结一下点分治的套路:这类题往往统计树上满足条件的点对的个数(或是寻找最优点对),一旦看到树上统计点对这样的类型,就可以考虑点分治了,平时记得多看看,不要忘了模板怎么打。

\(D\) 题考试时有点线段树合并的思路,但是考试的时候在一个点上卡住了。

为了计算两棵线段树对应集合的逆序对数(顺便在此过程合并),我们实际上采用了一点分治的思想,也就是分 \(3\) 类计算,前二者是左右子树内部的,后者是跨子树的,然后因为我们是递归合并线段树的,因此这恰好为分治提供了很好的载体,于是就有了这样的计算:

void merge(int &x,int y,int l,int r)
{
	if(!x||!y)
	{
		x|=y;
		return ;
	}
	ans1+=1ll*val[ls[x]]*val[rs[y]];//正序对
	ans2+=1ll*val[rs[x]]*val[ls[y]];//逆序对
	if(l==r)
	{
		val[x]+=val[y];
		return ;
	}
	int mid=l+r>>1;
	merge(ls[x],ls[y],l,mid),merge(rs[x],rs[y],mid+1,r);
	val[x]=val[ls[x]]+val[rs[x]];
}

权当教训。

posted @ 2022-07-31 22:05  Freshair_qprt  阅读(24)  评论(0编辑  收藏  举报