[codeforces722E] Research Rover
来源:互联网 发布:微软办公软件mac版 编辑:程序博客网 时间:2024/06/05 02:53
题目大意
有一个n*m的网格图,你要从(1,1)走到(n,m),每一步可以向右(或向下)走。你最开始有s点能量,然而有k个障碍点,每到达一个障碍点,你的能量会变成
数据范围
n,m≤100000 k≤2000 1≤s≤1000000
分析
首先可以发现,s最终变成1后,一直变化都是1,所以s最多只有
把障碍点排序,这是一定要的。并且把(n,m)也看成障碍点
然后可以设f[i][j]表示走到第j个障碍点,经过i个障碍点的答案。我们发现如果求每个点两两之间不经过任何其它障碍点的答案较难,所以可以考虑容斥。
设g[i][j],j和上面一样,i表示经过至少i个障碍点。容易求出f[0]、g[0]的值。然后对于i>0转移如下:
其中Ways[i][j]表示i到j的方案数,这个组合数算一下就好了。
#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#define fi first#define se secondusing namespace std;const int maxs=2005,maxn=200005,mo=1e9+7,N=22;typedef long long LL;typedef double db;typedef pair<int,int> PII;int n,m,k,s,M,Energy[N],f[N][maxs],g[N][maxs],All[maxs][maxs],Fac[maxn],Fac_Inv[maxn],Inv[maxn],ans;PII Point[maxs];char c;int read(){ for (c=getchar();c<'0' || c>'9';c=getchar()); int x=c-48; for (c=getchar();c>='0' && c<='9';c=getchar()) x=x*10+c-48; return x;}bool cmp(PII a,PII b){ return a.fi<b.fi || a.fi==b.fi && a.se<b.se;}void Init(){ n=read(); m=read(); k=read(); s=read(); for (int i=1;i<=k;i++) { Point[i].fi=read()-1; Point[i].se=read()-1; } sort(Point+1,Point+k+1,cmp); Point[++k].fi=n-1; Point[k].se=m-1; Point[0].fi=Point[0].se=0; Fac[0]=Fac_Inv[0]=Fac[1]=Fac_Inv[1]=Inv[1]=1; for (int i=2;i<=n+m;i++) { Fac[i]=(LL)Fac[i-1]*i%mo; Inv[i]=(LL)Inv[mo%i]*(mo-mo/i)%mo; Fac_Inv[i]=(LL)Fac_Inv[i-1]*Inv[i]%mo; } Energy[0]=s; while (s>1) Energy[++M]=s=ceil((db)s/2);}int Comb(int N,int M){ return (LL)Fac[N]*Fac_Inv[M]%mo*Fac_Inv[N-M]%mo;}void Work(){ for (int i=1;i<=k;i++) { f[0][i]=g[0][i]=Comb(Point[i].fi+Point[i].se,Point[i].fi); for (int j=1;j<i;j++) if (Point[i].se>=Point[j].se) { All[j][i]=Comb(Point[i].fi-Point[j].fi+Point[i].se-Point[j].se,Point[i].fi-Point[j].fi); f[0][i]=(f[0][i]+mo-(LL)f[0][j]*All[j][i]%mo)%mo; } } for (int i=1;i<=M;i++) { for (int j=i+1;j<=k;j++) { for (int x=i;x<j;x++) if (Point[x].se<=Point[j].se) g[i][j]=(g[i][j]+(LL)f[i-1][x]*All[x][j])%mo; f[i][j]=g[i][j]; for (int x=i;x<j;x++) if (Point[x].se<=Point[j].se) f[i][j]=(f[i][j]+mo-(LL)f[i][x]*All[x][j]%mo)%mo; } } ans=0; for (int i=0;i<M;i++) ans=(ans+(LL)Energy[i]*f[i][k]%mo)%mo; ans=(ans+g[M][k])%mo; ans=(LL)ans*Fac[n-1]%mo*Fac[m-1]%mo*Fac_Inv[n+m-2]%mo; printf("%d\n",ans);}int main(){ Init(); Work(); return 0;}
1 0
- [codeforces722E] Research Rover
- codeforces 722E. Research Rover
- Intel Code Challenge Elimination Round (Div.1 + Div.2, combined)E. Research Rover (容斥Lucas)
- Research
- Research
- apm-rover主程序分析
- Ground Rover with Mavros
- apm-rover主程序分析
- Problem E Red Rover kmp
- rimble GeoExplorer® GeoXR™ Network Rover
- gym 101196E Red Rover(枚举)
- APM::Rover下GCS_MAVLink的逻辑梳理
- Jcrontab Research
- Requirement Research
- Do research
- Research Code
- Research Proposal
- Phd Research
- 第9周项目3 -稀疏矩阵的三元组表示的实现及应用(1)
- android.content.res.Resources$NotFoundException
- 锁表 存储过程 JOB简介
- Cocos 3.0 第一天
- context.Server.MapPath()出现两个网站名
- [codeforces722E] Research Rover
- 计算无向连通图的割点和割边
- nginx gzip开启
- 执行shell脚本报错#!/bin/ksh: No such file or directory
- android actionbar再见
- 解决没在写保护情况下adb中一直卸载不了app的问题
- Protobuf语言指南
- A 'Brief' History of Neural Nets and Deep Learning, Part 1
- 进度环组件封装