zoukankan      html  css  js  c++  java
  • 「考试」省选73

    T1
    看起来是个状压(dp)
    (dp[i][j][S])为前(i)行,放置了(j)个哲学家,第(i)行放的情况是(S)的方案数。
    那么对于两个状态,能否由上一行转移到这一行会存在一些判断,这些判断暴力写一写就行了,也不是很恶心。
    对于两个状态能够转移的话(s_1 ightarrow s_2),那我们就用状压(dp)暴力的在两行之间转移就可以了。
    复杂度最劣是(O(3n^22^6))的。
    卡常可以过。
    比如说对于一个(i)(j)枚举的下界是(max(0,m-3(n-i+1)))这样子。
    然后看了一下神仙正解。
    如果我们把(dp(i,S))看成是({dp[i][S][j]})的生成函数。
    那么有:([x^j]dp(i,S)=dp[i][j][S])
    同时可以用矩阵进行转移。
    (dp(i))为一个列向量,每一个位置存(dp(i,S))就可以了。
    然后转移矩阵(A)有:(s_1 ightarrow s_2,a_{s_1,s_2}=x^{bit[s_2]})
    这样就可以直接用矩阵快速幂了。
    然而你直接用矩阵暴力乘多项式上去的复杂度就是(O(512nlog^2n))的。
    还不如暴力。
    考虑直接用点值乘,这样省去了一个(logn)
    (A^{n})的复杂度就是:(O(512nlogn))的了。

    T2
    是01分数规划。
    我们考虑如何(check)一个答案。
    相当于是有(Amid-B>0)则偏大,否则偏小。
    可以二分。
    (check)的时候算出来(Amid-B)的最大值就可以了,判断最大值是不是偏大。
    很显然的一个最大权闭合子图。
    两个点之间的贡献拆成两倍来做,这样(a[i])也要乘二才能保证上下相除答案不变。
    然后对于两个点的贡献分开割就可以了。
    网络流得卡常。
    我写了当前弧优化,然后被迫又把两条边合并。
    这才卡过去。

    T3
    很奇怪的找到三种算法(两种可行)。
    1.

    [ans=sumlimits_{i=1}^{n}2^{f(i)} ]

    [g(n)=2^{f(n)} ]

    [(a,b)=1,f(ab)=f(a)+f(b),g(ab)=g(a)g(b),g(p^e)=2p^0 ]

    这个东西可以发现是直接(Min\_25)筛就行。但是太难写了。
    所以我后面两个都是想推出一个复杂度比较优秀的暴力出来。

    [g(d)=2^{f(d)}=sumlimits_{g|d}[(g,frac{d}{g})=1] ]

    [egin{aligned} ans&=sumlimits_{i=1}^{n}g(i)\ &=sumlimits_{i=1}^{n}sumlimits_{d|i}[(d,frac{i}{d})=1]\ &=sumlimits_{i=1}^{n}sumlimits_{d|i}sumlimits_{g|(d,frac{i}{d})}mu(g)\ &=sumlimits_{d=1}^{n}sumlimits_{i=1}^{frac{n}{d}}sumlimits_{g|(d,i)}mu(g)\ &=sumlimits_{g=1}^{n}mu(g)sumlimits_{d=1}^{frac{n}{g}}frac{n}{dg}\ h(n)&=sumlimits_{i=1}^{n}frac{n}{i}\ &=sumlimits_{g=1}^{n}mu(g)h(frac{n}{g})\ end{aligned} ]

    前面的部分整除分块+杜教筛就可以算出来,后面的(h)也是可以用整除分块的,复杂度在线性左右(不会证)。
    这个算法中间的地方有一些性质没有挖掘出来。
    其实本质上是和最终算法是相同的。
    只不过最终算法把这个算法的枚举给合并同类项了。

    [g(d)=2^{f(d)}=sumlimits_{g|d}[(g,frac{d}{g})=1] ]

    [egin{aligned} ans&=sumlimits_{i=1}^{n}g(i)\ &=sumlimits_{i=1}^{n}sumlimits_{d|i}[(d,frac{i}{d})=1]\ &=sumlimits_{i=1}^{n}sumlimits_{d|i}sumlimits_{g|(d,frac{i}{d})}mu(g)\ &=sumlimits_{i=1}^{n}sumlimits_{g^2|i}mu(g)d(frac{i}{g^2})\ &=sumlimits_{g=1}^{sqrt{n}}mu(g)sumlimits_{i=1}^{frac{n}{g^2}}d(i)\ &=sumlimits_{g=1}^{sqrt{n}}mu(g)sumlimits_{i=1}^{frac{n}{g^2}}sumlimits_{d|i}I\ &=sumlimits_{g=1}^{sqrt{n}}mu(g)sumlimits_{d=1}^{frac{n}{g^2}}frac{n}{g^2d}\ &=sumlimits_{g=1}^{sqrt{n}}mu(g)l(frac{n}{g^2})\ l(n)&=sumlimits_{i=1}^{n}frac{n}{i}\ end{aligned} ]

    前面枚举(g),然后分块算(l(frac{n}{g^2}))即可。
    这个算法的话时间复杂度也很优秀。

    [O=int_1^{sqrt{n}}sqrt{frac{n}{x^2}}dx=sqrt{n}sumlimits_{x=1}^{sqrt{n}}frac{1}{x}dx=sqrt{n}ln(sqrt{n}) ]

    这样就解决了。

  • 相关阅读:
    光照模型
    多线程编程(7)Semaphore信号量
    多线程编程(3)
    Oracle SQL*plus常用的命令和函数
    经典的开发工具
    Windows 7/Vista下通过组策略禁止USB接口
    浅谈.NET下的多线程
    SQLServer和Oracle常用函数对比
    注册表操作类
    利用using和try/finally语句来清理资源
  • 原文地址:https://www.cnblogs.com/Lrefrain/p/12720071.html
Copyright © 2011-2022 走看看