2019牛客多校第二场BEddy Walker 2——BM递推
题意
从数字 $0$ 除法,每次向前走 $i$ 步,$i$ 是 $1 \sim K$ 中等概率随机的一个数,也就是说概率都是 $\frac{1}{K}$。求落在过数字 $N$ 额概率,$N=-1$ 表示无穷远。
分析
设落在过 $i$ 的概率为 $p_i$,则 $p_i = \frac{1}{K}p_{i-1} + \frac{1}{K}p_{i-2}...+\frac{1}{K}p_{i-k}$.
以 $k=2$ 为例,
$p_0 = 1 \\
p_1 = \frac{1}{2} \\
p_2 = \frac{1}{2}(\frac{1}{2} + 1) = \frac{3}{4} \\
p_3 = \frac{1}{2}(\frac{3}{4} + \frac{1}{2}) = \frac{5}{8} \\
p_4 = \frac{1}{2}(\frac{5}{8} + \frac{3}{4}) = \frac{11}{16}$
容易推出 $p_n = \frac{\frac{2}{3}\cdot 2^n + \frac{1}{3}\cdot (-1)^n}{2^n}$,
可知,当 $n \to \infty$,$p_n=\frac{2}{3}$.
找规律,能发现 $n$ 为无穷大时 $p_n = \frac{2}{k+1}$
//$ 1 \leq K_i \leq 1021, -1 \leq N_i \leq 10^{18}$,矩阵快速幂会TLE的
- #include <bits/stdc++.h>
- using namespace std;
- #define rep(i,a,n) for (long long i=a;i<n;i++)
- #define per(i,a,n) for (long long i=n-1;i>=a;i--)
- #define pb push_back
- #define mp make_pair
- #define all(x) (x).begin(),(x).end()
- #define fi first
- #define se second
- #define SZ(x) ((long long)(x).size())
- typedef vector<long long> VI;
- typedef long long ll;
- typedef pair<long long,long long> PII;
- const ll mod=;
- ll powmod(ll a,ll b) {ll res=;a%=mod; assert(b>=); for(;b;b>>=){if(b&)res=res*a%mod;a=a*a%mod;}return res;}
- // head
- long long _,n;
- namespace linear_seq
- {
- const long long N=;
- ll res[N],base[N],_c[N],_md[N];
- vector<long long> Md;
- void mul(ll *a,ll *b,long long k)
- {
- rep(i,,k+k) _c[i]=;
- rep(i,,k) if (a[i]) rep(j,,k)
- _c[i+j]=(_c[i+j]+a[i]*b[j])%mod;
- for (long long i=k+k-;i>=k;i--) if (_c[i])
- rep(j,,SZ(Md)) _c[i-k+Md[j]]=(_c[i-k+Md[j]]-_c[i]*_md[Md[j]])%mod;
- rep(i,,k) a[i]=_c[i];
- }
- long long solve(ll n,VI a,VI b)
- { // a 系数 b 初值 b[n+1]=a[0]*b[n]+...
- // printf("%d\n",SZ(b));
- ll ans=,pnt=;
- long long k=SZ(a);
- assert(SZ(a)==SZ(b));
- rep(i,,k) _md[k--i]=-a[i];_md[k]=;
- Md.clear();
- rep(i,,k) if (_md[i]!=) Md.push_back(i);
- rep(i,,k) res[i]=base[i]=;
- res[]=;
- while ((1ll<<pnt)<=n) pnt++;
- for (long long p=pnt;p>=;p--)
- {
- mul(res,res,k);
- if ((n>>p)&)
- {
- for (long long i=k-;i>=;i--) res[i+]=res[i];res[]=;
- rep(j,,SZ(Md)) res[Md[j]]=(res[Md[j]]-res[k]*_md[Md[j]])%mod;
- }
- }
- rep(i,,k) ans=(ans+res[i]*b[i])%mod;
- if (ans<) ans+=mod;
- return ans;
- }
- VI BM(VI s)
- {
- VI C(,),B(,);
- long long L=,m=,b=;
- rep(n,,SZ(s))
- {
- ll d=;
- rep(i,,L+) d=(d+(ll)C[i]*s[n-i])%mod;
- if (d==) ++m;
- else if (*L<=n)
- {
- VI T=C;
- ll c=mod-d*powmod(b,mod-)%mod;
- while (SZ(C)<SZ(B)+m) C.pb();
- rep(i,,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
- L=n+-L; B=T; b=d; m=;
- }
- else
- {
- ll c=mod-d*powmod(b,mod-)%mod;
- while (SZ(C)<SZ(B)+m) C.pb();
- rep(i,,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
- ++m;
- }
- }
- return C;
- }
- long long gao(VI a,ll n)
- {
- VI c=BM(a);
- c.erase(c.begin());
- rep(i,,SZ(c)) c[i]=(mod-c[i])%mod;
- return solve(n,c,VI(a.begin(),a.begin()+SZ(c)));
- }
- };
- ll qpow(ll a, ll b, ll p)
- {
- ll ret = ;
- while(b)
- {
- if(b & ) ret = ret * a % p;
- a = a * a % p;
- b >>= ;
- }
- return ret;
- }
- int k;
- vector<ll>p;
- int main()
- {
- int T;
- scanf("%d", &T);
- while(T--)
- {
- scanf("%d%lld", &k, &n);
- ll INV = qpow(k, mod-, mod);
- p.clear();
- p.push_back();
- for(int i = ;i < *k;i++) //求出前2k项,给BM
- {
- ll tmp = ;
- for(int j = i-;j >= i-k && j >= ;j--) tmp = (tmp + p[j]) % mod;
- p.push_back(tmp * INV % mod);
- }
- //for(int i = 0;i < 2*k;i++) printf("%lld ", p[i]);
- //printf("\n");
- /*输出系数*/
- /*前k项递推,需要2*k项能确定*/
- //VI res = linear_seq::BM(p);
- //for(int i = 1;i < res.size();i++) printf("%lld%c", (mod-res[i]) % mod, i == res.size()-1 ? '\n' : ' ');
- if(n == -) printf("%lld\n", * qpow(k+, mod-, mod) % mod);
- else printf("%I64d\n",linear_seq::gao(p, n));
- }
- }
参考链接:https://blog.nowcoder.net/n/c7beb081cf2247779d2fa198b73a6658
2019牛客多校第二场BEddy Walker 2——BM递推的更多相关文章
- 2019牛客多校第二场A-Eddy Walker
Eddy Walker 题目传送门 解题思路 因为走过所有的点就会停下来,又因为是从0出发的,所以当n>1时,在0停下来的概率为0,其他的为1/(n-1); 代码如下 #include < ...
- 2019牛客多校第二场 A Eddy Walker(概率推公式)
2019牛客多校第二场 A Eddy Walker(概率推公式) 传送门:https://ac.nowcoder.com/acm/contest/882/A 题意: 给你一个长度为n的环,标号从0~n ...
- 2019牛客多校第二场H-Second Large Rectangle
Second Large Rectangle 题目传送门 解题思路 先求出每个点上的高,再利用单调栈分别求出每个点左右两边第一个高小于自己的位置,从而而得出最后一个大于等于自己的位置,进而求出自己的位 ...
- [2019牛客多校第二场][G. Polygons]
题目链接:https://ac.nowcoder.com/acm/contest/882/G 题目大意:有\(n\)条直线将平面分成若干个区域,要求处理\(m\)次询问:求第\(q\)大的区域面积.保 ...
- 2019 牛客多校第二场 H Second Large Rectangle
题目链接:https://ac.nowcoder.com/acm/contest/882/H 题目大意 给定一个 n * m 的 01 矩阵,求其中第二大的子矩阵,子矩阵元素必须全部为 1.输出其大小 ...
- 2019牛客多校第二场H题(悬线法)
把以前的题补补,用悬线求面积第二大的子矩形.我们先求出最大子矩阵的面积,并记录其行三个方向上的悬线长度.然后排除这个矩形,记得还得特判少一行或者少一列的情况 #include <bits/std ...
- 2019牛客多校第二场D-Kth Minimum Clique
Kth Minimum Clique 题目传送门 解题思路 我们可以从没有点开始,把点一个一个放进去,先把放入一个点的情况都存进按照权值排序的优先队列,每次在新出队的集合里增加一个新的点,为了避免重复 ...
- 2019牛客多校第二场F-Partition problem(搜索+剪枝)
Partition problem 题目传送门 解题思路 假设当前两队的对抗值为s,如果把红队中的一个人a分配到白队,s+= a对红队中所有人的对抗值,s-= a对白队中所有人的对抗值.所以我们可以先 ...
- [2019牛客多校第二场][A. Eddy Walker]
题目链接:https://ac.nowcoder.com/acm/contest/882/A 题目大意:圆上有\(n\)个点,标号从\(0\)到\(n-1\),初始一个人在点\(0\),每次会等概率向 ...
随机推荐
- 013 ECMAScript基础应用
1.ECMAScript概述 (1)前端的发展历程 <1>web 1.0时代 最初的网页以HTML为主,是纯静态的网页.网页是只读的,信息流只能从服务的到客户端单向流通.开发人员也只关心页 ...
- 22 Oracle数据库基础入门
1.Oracle数据库的介绍 ORACLE 数据库系统是美国ORACLE 公司(甲骨文)提供的以分布式数据库为核心的一组软件产品,是目前最流行的客户/服务器(CLIENT/SERVER)或 B/S 体 ...
- go开发环境
1.go 下载地址 https://studygolang.com/dl 根据操作系统 下载相应的安装包 2.设置环境变量 goroot gopath path 增加%goroot%\bin 3.开发 ...
- Spring Boot Web 自定义返回值(通用)
在项目下新建common.entity包,包中包含两个文件Result数据类,ResultCode接口文件 Result.class @Data @NoArgsConstructor public c ...
- PyCharm+QTDesigner学习
PyCharm+QTDesigner+PyUIC使用教程:https://www.cnblogs.com/lsdb/p/9122425.html python用pyinstaller生成exe时报错 ...
- 复制Linux虚拟机(VMware vSphere Client 工具)
1.VMware vSphere Client 工具 登录,如下图 IP.用户名/密码均是物理机,登录完成界面: 2.选择一个复制的原虚拟机 A,点击左上角[文件]——导出——导出O ...
- java之mybatis之缓存
1.mybatis自带缓存功能.分为一级缓存,二级缓存. 2.一级缓存为 session 缓存,在一个 session中 ,一个查询的 select 语句只会执行一次,根据 <select&g ...
- java之spring mvc之页面跳转
1. 如果返回值为ModelAndView,在处理方法中,返回null时,默认跳转的视图名称为请求名.跳转结果会根据视图解析器来跳转. @RequestMapping("/hello.do& ...
- XXL-JOB使用命令行的方式启动python时,日志过多导致阻塞的解决方式
一.Runtime.getRuntime().exec()的阻塞问题 这个问题也不能算是XXL-JOB的问题,而是Java的Runtime.getRuntime().exec()造成的,Buffere ...
- Function.prototype.apply.call 理解分析
首先需要了解apply,call的基本用法,其目的是改变调用方法中的this指向,将其指向为传入的对象,改变this的指向,两种方法接收参数的方式不同. 代码:console.log var cons ...