DP式子比后面的东西难推多了

LOJ2304

Luogu P3824

UOJ #316


题意

给定一个长度为$ n$高为$ \infty$的矩形

每个点有$ 1-P$的概率不可被选择

求最大的和底边重合的不包含不可选点的矩形的面积为$ K$的概率

$ n \leq 10^9 k \leq 10^3$


题解

K可以出到50000的

首先考虑DP

面积恰好为$ K$的概率可以差分为不高于$ K$的概率减去不高于$ K-1$的概率

设$ f[i][j]$表示长度为$ i$的矩形,从底边起$ j$行都可选,最大面积不大于$ K$的概率

边界为$ f[0][j]=1,f[i][j]=0 当且仅当i*j>k$

考虑转移,要么第$ j+1$行也都可选,要么第$ j+1$行有不可选的位置

对于第二种情况我们枚举从左到右第一个不可选的位置

有转移方程式

$$f[i][j]=f[i][j+1]*P^i+\sum_{k=1}^iP^{k-1}(1-P)f[k-1][j+1]·f[i-k][j]$$

我们要求的是$ f[n][0]$

由于$ i*j \leq K$因此复杂度大致是$ n·k \log k$的

可以得$ 70$分

容易发现当$ n$远大于$ k$的时候,每连续$ k$列必然有一列最低端有不可选点

令$ F[i]$表示当$ i>k$时,长度为$ i$的矩形的答案

枚举从右往左第一个不可选点,有转移方程式

$$ F[i]=f[i-k]*(1-P)*f[k-1][1]*P^{k-1}$$

这是一个线性递推的标准形式,可以用特征多项式优化到$ O(k^2 \log n)$甚至$ O(k \log k \log n)$

如果采用后一种的话复杂度的瓶颈在于前面的$ O(k^2)DP$,这部分可以用分治$ NTT$优化

然而我并没有写


代码

#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#define p 998244353
#define rt register int
#define ll long long
using namespace std;
inline ll read(){ll x=0;char zf=1;char ch=getchar();while(ch!='-'&&!isdigit(ch))ch=getchar();if(ch=='-')zf=-1,ch=getchar();while(isdigit(ch))x=x*10+ch-'0',ch=getchar();return x*zf;
}
void write(ll y){if(y<0)putchar('-'),y=-y;if(y>9)write(y/10);putchar(y%10+48);}
void writeln(const ll y){write(y);putchar('\n');}
namespace poly{vector<int>R;int ksm(int x,int y=p-2){int ans=1;for(rt i=y;i;i>>=1,x=1ll*x*x%p)if(i&1)ans=1ll*ans*x%p;return ans;}void NTT(int n,vector<int>&A,int fla){A.resize(n);for(rt i=0;i<n;i++)if(i>R[i])swap(A[i],A[R[i]]);for(rt i=1;i<n;i<<=1){int w=ksm(3,(p-1)/2/i);for(rt j=0;j<n;j+=i<<1){int K=1;for(rt k=0;k<i;k++,K=1ll*K*w%p){int x=A[j+k],y=1ll*K*A[i+j+k]%p;A[j+k]=(x+y)%p,A[i+j+k]=(x-y)%p;}}}if(fla==-1){reverse(A.begin()+1,A.end());int invn=ksm(n);for(rt i=0;i<n;i++)A[i]=1ll*A[i]*invn%p;}}vector<int>Mul(vector<int>x,vector<int>y){int lim=1,sz=x.size()+y.size()-1;while(lim<=sz)lim<<=1;R.resize(lim);for(rt i=0;i<lim;i++)R[i]=(R[i>>1]>>1)|(i&1)*(lim>>1);NTT(lim,x,1);NTT(lim,y,1);for(rt i=0;i<lim;i++)x[i]=1ll*x[i]*y[i]%p;NTT(lim,x,-1);x.resize(sz);return x;}vector<int>sqr(vector<int>x){int lim=1,sz=x.size()*2-1;while(lim<=sz)lim<<=1;R.resize(lim);for(rt i=0;i<lim;i++)R[i]=(R[i>>1]>>1)|(i&1)*(lim>>1);NTT(lim,x,1);for(rt i=0;i<lim;i++)x[i]=1ll*x[i]*x[i]%p;NTT(lim,x,-1);x.resize(sz);return x;}vector<int>Inv(vector<int>A,int n=-1){if(n==-1)n=A.size();if(n==1)return vector<int>(1,ksm(A[0]));vector<int>b=Inv(A,(n+1)/2);int lim=1;while(lim<=n+n)lim<<=1;R.resize(lim);for(rt i=0;i<lim;i++)R[i]=(R[i>>1]>>1)|(i&1)*(lim>>1);A.resize(n);NTT(lim,A,1);NTT(lim,b,1);for(rt i=0;i<lim;i++)A[i]=1ll*b[i]*(2ll-1ll*A[i]*b[i]%p)%p;NTT(lim,A,-1);A.resize(n);return A;}vector<int>Div(vector<int>A,vector<int>B){int n=A.size(),m=B.size();reverse(A.begin(),A.end());reverse(B.begin(),B.end());A.resize(n-m+1),B.resize(n-m+1);int lim=1;while(lim<=2*(n-m+1))lim<<=1;R.resize(lim);for(rt i=0;i<lim;i++)R[i]=(R[i>>1]>>1)|(i&1)*(lim>>1);vector<int>ans=Mul(A,Inv(B));ans.resize(n-m+1);reverse(ans.begin(),ans.end());return ans;}vector<int>add(vector<int>A,vector<int>B){int len=max(A.size(),B.size());A.resize(len+1);for(rt i=0;i<=len;i++)(A[i]+=B[i])%=p;return A;}vector<int>sub(vector<int>A,vector<int>B){int len=max(A.size(),B.size());A.resize(len+1);for(rt i=0;i<=len;i++)(A[i]-=B[i])%=p;return A;}vector<int>Mod(vector<int>x,vector<int>y){if(x.size()<=y.size())return x;vector<int>ans=Div(x,y);ans=sub(x,Mul(y,ans));while(!ans[ans.size()-1])ans.pop_back();if(ans.size()>y.size())ans.resize(y.size());return ans;}
}
using namespace poly;
int a[100010];
vector<int>fmo;
vector<int>ksm(vector<int>x,int y){if(y==1)return x;vector<int>ans=Mod(sqr(ksm(x,y>>1)),fmo);if(y&1){ans.push_back(0);for(rt i=ans.size()-2;i>=0;i--)ans[i+1]=ans[i],ans[i]=0;}return ans;
}
using namespace poly;
int k,m,n,x,y,z,cnt,ans,K,P;
int f[1010][1010],mi[1010];
//f[i][j]长度为i合法高度最低至少为j的合法概率
void calc(int n,int K,int fla){memset(f,0,sizeof(f));for(rt i=0;i<=K+10;i++)f[0][i]=1;for(rt i=1;i<=K+2;i++)for(rt j=K/i;j>=0;j--){f[i][j]=1ll*f[i][j+1]*mi[i]%p;for(rt k=1;k<=i;k++)(f[i][j]+=1ll*f[k-1][j+1]*mi[k-1]%p*(1+p-P)%p*f[i-k][j]%p)%=p;}fmo.resize(K+2);for(rt j=1;j<=K+1;j++)fmo[K+1-j]=-1ll*mi[j-1]*f[j-1][1]%p*(p+1-P)%p;fmo[K+1]=1;int ret=0;if(n<=K+1)ret=f[n][0];else {vector<int>x;x.push_back(0);x.push_back(1);x=ksm(x,n);for(rt i=0;i<=K+1;i++)(ret+=1ll*f[i][0]*x[i]%p)%=p;}(ans+=ret*fla)%=p;
}
int main(){
//    file("pool");n=read();K=read();x=read();y=read();P=1ll*x*ksm(y)%p;mi[0]=1;for(rt i=1;i<=K+2;i++)mi[i]=1ll*mi[i-1]*P%p;calc(n,K,1);calc(n,K-1,-1);cout<<(ans+p)%p;return 0;
}

转载于:https://www.cnblogs.com/DreamlessDreams/p/10251391.html

「NOI2017」泳池相关推荐

  1. loj #2305. 「NOI2017」游戏

    #2305. 「NOI2017」游戏 题目描述 小 L 计划进行 nnn 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏. 小 L 的赛车有三辆,分别用大写字母 AAA.BBB. ...

  2. LibreOJ2302 - 「NOI2017」整数

    Portal Description 有一个整数\(x=0\),对其进行\(n(n\leq10^6)\)次操作: 给出\(a(|a|\leq10^9),b(b\leq30n)\),将\(x\)加上\( ...

  3. 如何直观地理解「协方差矩阵」?

    如何直观地理解「协方差矩阵」? Xinyu Chen Urban Traffic Data Analytics 372 人赞同了该文章 协方差矩阵在统计学和机器学习中随处可见,一般而言,可视作方差和协 ...

  4. 消除左递归实验代码_「leetcode」108. 构造二叉搜索树【递归】【迭代】详解!

    构造二叉搜索树,一不小心就平衡了 ❞ 108.将有序数组转换为二叉搜索树 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树 ...

  5. 不带头节点的链表有哪些缺点_23张图!万字详解「链表」,从小白到大佬!

    链表和数组是数据类型中两个重要又常用的基础数据类型. 数组是连续存储在内存中的数据结构,因此它的优势是可以通过下标迅速的找到元素的位置,而它的缺点则是在插入和删除元素时会导致大量元素的被迫移动,为了解 ...

  6. 一位老码农的分享:一线程序员该如何面对「中年危机」?

    如果这是第二次看到我的文章,欢迎文末扫码订阅我个人的公众号(跨界架构师)哟~   本文长度为2728字,建议阅读8分钟. 坚持原创,每一篇都是用心之作- 先来聊一下这个问题的背景吧. 前两天有小伙伴问 ...

  7. 机器人 Ameca「苏醒」瞬间逼真到令人恐惧,网友纷纷惊叹……

    整理 | 禾木木 出品 | AI科技大本营(ID:rgznai100) 近日,国内外网友都被一段机器人「苏醒」的视频惊讶到. 视频开始时,机器人似乎已经睡着,眼睛闭着,头部略微向下倾斜.随着肩膀的伸展 ...

  8. AI 复活「她」! GPT-3 帮美国小哥复刻逝去未婚妻,但又夺走她……

    整理 | 禾木木 出品 | AI科技大本营(ID:rgznai100) 今年 7 月,一名33岁的美国小哥 Joshua Barbeau 在未婚妻去世后,根据她在 Facebook 和 twitter ...

  9. OpenAI 以 10 亿美元出售「灵魂」,网友热评不再「Open」

    编译 | 禾木木 出品 | AI科技大本营(ID:rgznai100) OpenAI 如何以 10 亿美元的价格出售其灵魂:GPT-3 和 Codex 背后的公司并不像它声称的那样开放. 当金钱成为障 ...

最新文章

  1. 测试一下StringBuffer和StringBuilder及字面常量拼接三种字符串的效率
  2. 道县谋定农业创新-李加映:中国农民丰收节交易会产业化
  3. java多线程对数组求和_java 多线程 求和
  4. 在word文档里提取出所有的邮箱地址
  5. title与h1标签的区别和联系
  6. Git 忽略已经提交的文件
  7. 导航菜单UI设计中的作用,优秀案例临摹起来!
  8. 李洪强iOS经典面试题156 - Runtime详解(面试必备)
  9. 打开计算机后无法缩小怎么办,电脑打开窗口小怎么办
  10. 花老湿学习OpenCV:Shi-Tomasi角点检测
  11. unity shader中关于Tags的整理
  12. 破解无线路由器,获得微信等上网信息
  13. unity code-动作系统Animator
  14. 计算机考试五大软件,计算机软件水平考试应避免的五大失误
  15. 惠普服务器怎么挂载虚拟光驱,惠普服务器SPP包制做方法
  16. 教你如何不打线稿,用马克笔画出民居建筑
  17. 进来试试这份字节跳动面试题,看看你能打几分
  18. Android 9.0 蓝牙去掉传输文件的功能
  19. 【考研英语】态度题/情感词汇
  20. c++ 队列_Day 5:用两个栈实现队列

热门文章

  1. python剑指offer 包含min函数的栈
  2. ASP.NET Web Pages:表单
  3. Hibernate的工作原理
  4. controller实现pdf的下载功能
  5. none 和 host 网络的适用场景 - 每天5分钟玩转 Docker 容器技术(31)
  6. 网页授权有时候获取不到openid 的坑
  7. HTML基础标签入门
  8. BinaryWriter和BinaryReader用法
  9. poj 1200 Crazy Search
  10. [CNT]关于自己的一个小小的slab内存分配器