Sereja and Cinema

首先我们可以发现除了第一个人, 其他人都会坐在已入坐人的旁边。

难点在于计算方案数。。 我们可以从外往里把确定的人用组合数算上去,然后缩小范围。

#include<bits/stdc++.h>
#define LL long long
#define LD long double
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long using namespace std; const int N = 1e5 + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + ;
const double eps = 1e-;
const double PI = acos(-); template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;}
template<class T, class S> inline void sub(T& a, S b) {a -= b; if(a < ) a += mod;}
template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true : false;}
template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;} int power(int a, int b) {
int ans = ;
while(b) {
if(b & ) ans = 1LL * ans * a % mod;
a = 1LL * a * a % mod; b >>= ;
}
return ans;
} int inv[N], Finv[N], F[N];
void init() {
inv[] = F[] = Finv[] = ;
for(int i = ; i < N; i++) inv[i] = 1LL * (mod - mod / i) * inv[mod % i] % mod;
for(int i = ; i < N; i++) F[i] = 1LL * F[i - ] * i % mod;
for(int i = ; i < N; i++) Finv[i] = 1LL * Finv[i - ] * inv[i] % mod;
}
int comb(int n, int m) {
if(n < m || n < ) return ;
return 1LL * F[n] * Finv[m] % mod * Finv[n - m] % mod;
} int n, a[N], prefix[N]; int solve(int L, int R) {
if(prefix[L - ] == prefix[R]) return power(, R - L);
int p, q;
for(p = L; p <= R; p++) if(a[p] != ) break;
for(q = R; q >= L; q--) if(a[q] != ) break;
if(p == q && a[p] == ) return comb(R - L, p - L);
int ans = ;
if(a[p] >= a[q]) {
int L2 = p, R2 = L2 + a[p] - ;
if(R2 >= q && R2 <= R) add(ans, 1LL * solve(L2 + , R2) * comb(R - L - R2 + L2, L2 - L) % mod);
}
if(a[q] >= a[p]) {
int R2 = q, L2 = R2 - a[q] + ;
if(L2 >= L && L2 <= p) add(ans, 1LL * solve(L2, R2 - ) * comb(R - L - R2 + L2, L2 - L) % mod);
}
return ans;
} int main() {
init();
scanf("%d", &n);
for(int i = ; i <= n; i++) scanf("%d", &a[i]);
for(int i = ; i <= n; i++) prefix[i] = prefix[i - ] + (a[i] != );
printf("%d\n", solve(, n));
return ;
} /*
*/

最新文章

  1. 深入理解及应用Position
  2. 3dsMax用到的网格优化
  3. 关于Memcached一致性hash的探究
  4. php示例代码之类似于C#中的String.Format方法
  5. VBS使用Scripting.Dictionary字典对象
  6. 推荐算法&mdash;&mdash;距离算法
  7. asc.desc
  8. 告别无止境的增删改查:Java代码生成器
  9. hadoop2.2原理: 序列化浅析
  10. 利用switch语句进行多选一判断。
  11. NHibernate初入门之配置文件属性说明(四)
  12. Android kxml解析WBXML
  13. Unity3D第三人称摄像机控制脚本
  14. leetcode — word-break-ii
  15. 用C#编写Linux守护进程
  16. python3 第十八章 - 迭代器与生成器
  17. 【Spring源码深度解析学习系列】默认标签解析(三)
  18. thymeleaf循环
  19. Bus Hound抓包分析,基于HID设备(原创)
  20. Session重点整理

热门文章

  1. elasticsearch5.0.1集群排错的几个思路总结
  2. Uncaught RangeError: Maximum call stack size exceeded
  3. python decorators
  4. Tomcat服务的安装及配置
  5. 51nod--1265 四点共面 (计算几何基础, 点积, 叉积)
  6. Laravel 5.2--改变数据库字段值,编辑时候,默认选中
  7. Druid监控页面配置与使用
  8. 行为驱动:BDD框架之Cucumber初探
  9. nodejs process.memoryUsage() rss等参数啥含义
  10. Webapi 跨域 解决解决错误No &#39;Access-Control-Allow-Origin&#39; header is present on the requested resource 问题