zoukankan      html  css  js  c++  java
  • CodeCraft-19 and Codeforces Round #537 (Div. 2)

    23:35打到1:25,,,太困了直接去睡了。。。

    题目:http://codeforces.com/contest/1111

    题解:http://codeforces.com/blog/entry/64989

    A:模拟

    B:考虑枚举删除i个,一定是最小的i个,剩下的总共的贡献是:min(k*(n-i),m-i)

      但是要注意的是,i<=m!!,否则不合法,而且可能得到更优的答案

    C:分治dp。开始脑残直接递归到底。。。O(nklogk)。一共n层,不二分也可以,每段直接暴力枚举找到划分位置。O(nk)

    D:(开始没有注意到所有的字母都要满足全部都出现在某一半。。FST)

    显然要先考虑没有(x,y)限制的

    分成两个部分考虑问题

    如果我们把一些字母都划分到n/2里,剩下的在另一半,那么内部再排列的方案数永远是:W=((n/2)!(n/2)!)/(cnt[a]!*cnt[b]!...cnt[Z]!)

    所以,我们只要求把52个字母划分到n/2个位置的方案数

    直接0/1背包搞定

    最后的ans是dp[n/2]*2*W

    考虑加上(x,y)的限制

    相当于钦定(x,y)必须放在某一半,其他随便放

    考虑没有x,y的那一半,所以等价于:不用x,y,填满n/2位置的方案数

    就是一个背包上修改的问题

    考虑总共只有52*52对,不妨预处理ans[i][j]

    消掉影响的话,把原来的dp数组copy一份叫做cp,

    for(int i=buc[x];i<=n;++i){

      cp[i]-=cp[i-buc[x]]

    }

    内层枚举y再做一次

    然后ans[i][j]=2*cp[n/2]*W

    O(n*52*52)

    E:

    m<=300,sumk<=1e5,启示我们O(m∑k)

    发现,一个点的所有祖先,假设有h[i]个,必然都在不同的集合

    所以,如果我们把k个点的h[i]求出来,按照h[i]从小到大排序

    dp,设dp[i][j]表示,前i个点,分成j个非空集合的方案数

    dp[i][j]=dp[i-1][j]*(j-h[i])+dp[i-1][j-1]

    (有点类似第二类斯特林数)

    考虑求出h[i]

    1.如果rt=1,直接dfn序,对子树用线段树处理即可

    2.如果rt=r,讨论一下,找到对应的子树(原来的或者取反(两块))处理即可

      也可以避免讨论,其实就是i到Y路径上标记点的个数。h[i]表示rt=1时i到根路径上标记点的数量(祖先数量+1,因为包括自己),hnew[i]=h[i]+h[Y]-2*h[lca(i,Y)]+[mark[lca(i,Y)]==true]-1(减掉i自己)

    复杂度:O(m∑k+∑klogN)

  • 相关阅读:
    css的书写位置+元素分类
    选择器
    我的js运动库新
    js的相关距离
    关于小乌龟的使用
    linux 基础
    linux shell快捷操作【超级实用】
    算法面试常见问题【转】
    http://www.cnblogs.com/zhangchaoyang/archive/2012/08/28/2660929.html
    cocos2dx + vs安装使用
  • 原文地址:https://www.cnblogs.com/Miracevin/p/10351517.html
Copyright © 2011-2022 走看看