[NOI2017]泳池

实在没有思路啊~~~

luogu题解

1.差分,转化成至多k的概率减去至多k-1的概率。这样就不用记录“有没有出现k”这个信息了

2.n是1e9,感觉要递推然后利用数列的加速技巧

f[n]表示宽度为n的值,然后枚举最后一个连续高度至少为1的块,dp数组辅助

神仙dp:dp[i][j]表示宽度为i,j的高度出现限制,任意矩形不大于k的概率

设计确实巧妙:宽度利于转移给f,高度利于自己的转移

dp数组转移:枚举第一个到达j的限制的位置,这样,前面部分限制至少是j+1,后面至少是j,中间概率是P^(j-1)*(1-P)

    并且,若i*j<=k,那么新增的就是中间的i*j的矩形,两边都满足的情况下,现在也一定满足

  后缀和优化,限制j的范围,调和级数可以证明状态实际上只有klogk个,转移O(k)

边界:f[0]=1,dp[0][*]=1,注意,*是0~k+2

3.我们现在得到了f的递推式

先递推找到f的前几项

k范围限制不能矩乘

利用[学习笔记]Cayley-Hilmiton

可以倍增加多项式取模

k<=1000可以暴力取模

发现,模数的最高项是1,所以不用逆元!

O(k^2(logn+logk))

代码:

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define numb (ch^'0')
#define int long long
using namespace std;
typedef long long ll;
il void rd(int &x){
    ;bool fl=false;
    while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
    +numb);
    (fl==true)&&(x=-x);
}
namespace Miracle{
;
;
ll a[*N],b[*N],f[*N],yu[*N],ret[*N];
ll dp[*N][*N];
ll mi[*N];
ll n,k,x,y;
ll P;
ll ans;
ll qm(ll x,ll y){
    ll ret=;
    while(y){
        ) ret=ret*x%mod;
        x=x*x%mod;
        y>>=;
    }
    return ret;
}
void mul(ll *f,ll *g,ll *mo,int n){
    memset(b,,sizeof b);
    ;i<=n;++i){
        ;j<=n;++j){
            b[i+j]=(b[i+j]+f[i]*g[j]%mod)%mod;
        }
    }
    *n;i>=n;--i){
        if(b[i])
            ;j<=n;++j) b[i+j-n]=(b[i+j-n]+mod-b[i]*mo[j]%mod)%mod;
    }
    ;i<=n;++i) f[i]=b[i],b[i]=;
    ;i<=*n;++i) f[i]=,b[i]=;
}
ll calc(int k){
    memset(dp,,sizeof dp);
    ;i<=k+;++i) dp[][i]=;
    ;i<=k;++i){
        ;j>=;--j){
            ;l<=i;++l){
                dp[i][j]=(dp[i][j]+dp[l-][j+]*dp[i-l][j]%mod*(+mod-P)%mod*mi[j-]%mod)%mod;
            }
            dp[i][j]=(dp[i][j+]+dp[i][j])%mod;
        }
    }
    ;i<=k;++i) a[k-i]=(mod-dp[i][]*(+mod-P)%mod)%mod;
    a[k+]=;
    memset(f,,sizeof f);
    f[]=;
    ;l<=*k;++l){
        ;i<=l;++i){
            >=) f[l]=(f[l]+f[l-i-]*dp[i][]%mod*(+mod-P)%mod)%mod;
            ])%mod;
        }
    }
    *k) return f[n];
    int y=n;
    memset(ret,,sizeof ret);
    memset(yu,,sizeof yu);
    ret[]=;
    yu[]=;
    while(y){
        ) mul(ret,yu,a,k+);
        mul(yu,yu,a,k+);
        y>>=;
    }
    ll bac=;
    ;i<=k;++i){
        bac=(bac+ret[i]*f[i]%mod)%mod;
    }
    return bac;
}
int main(){
    scanf("%lld%lld%lld%lld",&n,&k,&x,&y);
    P=x*qm(y,mod-)%mod;
    int lp=k;
    mi[]=;
    ;i<=k;++i) mi[i]=mi[i-]*P%mod;
    printf()+mod)%mod);
    ;
}

}
signed main(){
    Miracle::main();
    ;
}

/*
   Author: *Miracle*
   Date: 2019/2/25 16:31:18
*/

总结:
1.DP还是有一点套路可循的,f是枚举最后连续的段,dp是枚举第一个限制到j的位置

2.线性递推的优化方法。

[NOI2017]泳池——概率DP+线性递推的更多相关文章

  1. 【BZOJ4944】【NOI2017】泳池 概率DP 常系数线性递推 特征多项式 多项式取模

    题目大意 有一个\(1001\times n\)的的网格,每个格子有\(q\)的概率是安全的,\(1-q\)的概率是危险的. 定义一个矩形是合法的当且仅当: 这个矩形中每个格子都是安全的 必须紧贴网格 ...

  2. codeforces 696C PLEASE 概率dp+公式递推+费马小定理

    题意:有3个杯子,排放一行,刚开始钥匙在中间的杯子,每次操作,将左右两边任意一个杯子进行交换,问n次操作后钥匙在中间杯子的概率 分析:考虑动态规划做法,dp[i]代表i次操作后的,钥匙在中间的概率,由 ...

  3. HDU - 6172:Array Challenge (BM线性递推)

    题意:给出,三个函数,h,b,a,然后T次询问,每次给出n,求sqrt(an); 思路:不会推,但是感觉a应该是线性的,这个时候我们就可以用BM线性递推,自己求出前几项,然后放到模板里,就可以求了. ...

  4. 利用Cayley-Hamilton theorem 优化矩阵线性递推

    平时有关线性递推的题,很多都可以利用矩阵乘法来解决. 时间复杂度一般是O(K3logn)因此对矩阵的规模限制比较大. 下面介绍一种利用利用Cayley-Hamilton theorem加速矩阵乘法的方 ...

  5. 矩阵乘法&amp;矩阵快速幂&amp;矩阵快速幂解决线性递推式

    矩阵乘法,顾名思义矩阵与矩阵相乘, 两矩阵可相乘的前提:第一个矩阵的行与第二个矩阵的列相等 相乘原则: a b     *     A B   =   a*A+b*C  a*c+b*D c d     ...

  6. 【Luogu4723】线性递推(常系数齐次线性递推)

    [Luogu4723]线性递推(常系数齐次线性递推) 题面 洛谷 题解 板子题QwQ,注意多项式除法那里每个多项式的系数,调了一天. #include<iostream> #include ...

  7. 【模板】BM + CH(线性递推式的求解,常系数齐次线性递推)

    这里所有的内容都将有关于一个线性递推: $f_{n} = \sum\limits_{i = 1}^{k} a_{i} * f_{n - i}$,其中$f_{0}, f_{1}, ... , f_{k ...

  8. [JZOJ6088] [BZOJ5376] [loj #2463]【2018集训队互测Day 1】完美的旅行【线性递推】【多项式】【FWT】

    Description Solution 我们考虑将问题一步步拆解 第一步求出\(F_{S,i}\)表示一次旅行按位与的值为S,走了i步的方案数. 第二步答案是\(F_{S,i}\)的二维重复卷积,记 ...

  9. [AHOI2009]中国象棋 DP,递推,组合数

    DP,递推,组合数 其实相当于就是一个递推推式子,然后要用到一点组合数的知识 一道很妙的题,因为不能互相攻击,所以任意行列不能有超过两个炮 首先令f[i][j][k]代表前i行,有j列为一个炮,有k列 ...

随机推荐

  1. greendao操作数据库的使用方法

    第一步:把greendao-1.3.0-beta-1,greendao-generator-1.3.1两个jar包加载到工程的lib的文件夹中,一定要右键点击Add As Library后才能使用. ...

  2. java中反射机制通过字节码文件对象获取字段和函数的方法

    pclass = Class.forName("get_class_method.Person"); //Field ageField = pclass.getField(&quo ...

  3. Array.asList()注意

    api: public static <T> List<T> asList(T... a) 返回一个受指定数组支持的固定大小的列表.(对返回列表的更改会“直接写”到数组.)此方 ...

  4. Acdream a + b

    http://acdream.info/problem?pid=1007 两个 long long 相乘会超long long #include <cstdio> #include < ...

  5. 关于bootstrap--列表(ol、ul)

    1.list-unstyled : 在<ol>(有序列表)</ol><ul>(无序列表)</ul>中加入class="list-styled& ...

  6. jQuery 3.0 的 Data

    jQuery 3.0 的 Data Snandy If you cannot hear the sound of the genuine in you, you will all of your li ...

  7. java类集框架(ArrayList,LinkedList,Vector区别)

    主要分两个接口:collection和Map 主要分三类:集合(set).列表(List).映射(Map)1.集合:没有重复对象,没有特定排序方式2.列表:对象按索引位置排序,可以有重复对象3.映射: ...

  8. Python+OpenCV图像处理(一)

    Python+OpenCV图像处理(一): 读取,写入和展示图片 调用摄像头拍照 调用摄像头录制视频 1. 读取.写入和展示图片 图像读入:cv2.imread() 使用函数cv2.imread() ...

  9. ssh简明安全规划

    禁止使用口令只允许使用密钥建立 SSH 连接 1.创建 SSH KEY 使用ssh-keygen生成一个密钥对,并且将公钥注册到服务器的 $HOME/.ssh/authorized_keys 文件. ...

  10. HiJson(Json格式化工具)64位中文版下载 v2.1.2

    链接:https://pan.baidu.com/s/15gMvig15iUjpqSX7nUZ-5Q 密码:8086