151221总结

HAOI2015


T1
一颗树上有 n 个点,让你将 m 个点染成黑色,使得颜色相同的点间的路径长度和最大
树形dp

F[i,j] 表示以 i 为根的子树选了 j 个黑点,子树内的所有被标记过的路径权值和


void DFS(int p,int fa)
{
    static LL tmp[maxn];
    fill(dp[p]+2,dp[p]+n+1,-INF);
    size[p]=1;
    for(int i=start[p];i;i=next[i])
        if(to[i]!=fa)
        {
            int q=to[i];
            DFS(to[i],p);
            fill(tmp,tmp+size[p]+size[q]+1,-INF);
            for(int j=0;j<=size[p];++j)
                for(int k=0;k<=size[q];++k)
                    tmp[j+k] = max(tmp[j+k],dp[p][j]+dp[q][k]+len[i]*(k*(m-k)+(size[q]-k)*(n-m-(size[q]-k))));
            size[p]+=size[q];
            for(int j=0;j<=size[p];++j)
                dp[p][j]=tmp[j];
        }
}


考虑那个二重循环,可以看做分别枚举两棵子树的每个点。你会发现,点对(u,v),只会在Tree_Dp(lca(u,v))处被考虑到,所以复杂度是O(n^2)
注意写的顺序,不然可能会T


需要的知识:树形DP



T2
裸的树链剖分,大家都写过。。。


T3
暴力30分没拿到TAT
如果你推出了SG函数,然后你就拿到了50分啦。。。
由数学归纳法(其实是打表),得到对于 N/i 相同的 N ,SG函数都相同,这样最多只有 sqrt(n) 块,然后可以二分查找了,T到70分。。。
发现对于70分的算法,相邻两块也有很多的值是一样的,然后就又可以优化了。。。
100标算没看懂TAT,70分的基础上搞一搞勉强水过。。。


复杂度:O(玄学)


需要的知识:SG函数


T4 set

变换与变回:

for(int i=0;i<n;++i)
	for(int j=0;j<N;++j)
		 if(j>>i&1)
			a[j]+=a[j^(1<<i)];
for(int i=0;i<n;++i)
	 for(int j=0;j<N;++j)
		if(j>>i&1)
			a[j]-=a[j^(1<<i)];


orz gjy


需要的知识:容斥


T5

对于 f (n) 有 f(n) = ∑ f(i) (max(0 , n-m) <= i < n)

显然我们可以得到一个m * m的矩阵 A 来求得f(n)

因为矩阵具有分配律和可加性 所以有 A * (B+C) = A * B + A * C

A ^ (x1 + x2 + ...... xn) = A ^ x1 * A ^ x2 * ...... * A ^ xn

ans = ∑ (A * B) = ( ∑ A )* B

求 ∑A 时可以用dp

先预处理出每一段的 A^x 值记为seg[i,j]

状态转移: f[i]=∑ f[j] * seq[j+1][i] (j < i)

最后再乘上矩阵 B 就行了


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值