题意略。

思路:

I.对于整个区间a1,....,an,必然有一个区间[1,n]与之对应,因为a1,...,an是1,...,n的一个排列,所以在[1,n]中定然有一个最小的数字1,

如果最大的区间[l,r]长度比[1,n]小,那么我们可以知道在[l,r]之外的数字是依然大于1的,这使得1这个数字没有合法的地方可放。

II.起于1左端的区间不可能终于1的右端。

III.数字1左端的部分类似于整体,因为左端也类似地有一个最小的数字。

IV.要想知道整体的方案数有多少,假设可以由f(1,n)算出,那么f(1,n) = f(1,mid - 1) * f(mid + 1,r) * C(n - 1,mid - 1)。

V.这个题递归的顺序可以预先算出来。

#include<bits/stdc++.h>
//#pragma comment(linker,"/STACK:1024000000,1024000000")
using namespace std;
typedef long long LL;
const LL mod = 1e9 + ;
const LL maxn = 1e6 + ; inline bool scan_d(int& ret){
char c;int sgn;
if(c = getchar(),c == EOF) return ;
while(c != '-' && (c < '' || c > '')) c = getchar();
sgn = (c == '-') ? - : ;
ret = (c == '-') ? : (c - '');
while(c = getchar(),c >= '' && c <= '') ret = ret * + (c - '');
ret *= sgn;
return ;
} struct node{
int l,r,id;
node(int a = ,int b = ){
l = a,r = b;
}
bool operator<(const node& nd) const{
if(l != nd.l) return l < nd.l;
return r > nd.r;
}
}; int cnt;
LL fac[maxn],inv[maxn];
node store[maxn];
bool flag; LL exgcd(LL a,LL b,LL& x,LL& y){
if(a == && b == ) return -;
if(b == ){
x = ,y = ;
return a;
}
LL d = exgcd(b,a % b,y,x);
y -= a / b * x;
return d;
}
LL rev(LL a,LL n){
LL x,y;
LL d = exgcd(a,n,x,y);
if(d == ) return (x % n + n) % n;
else return -;
}
void init(){
fac[] = ;
for(LL i = ;i < maxn;++i) fac[i] = fac[i - ] * i % mod; inv[maxn - ] = rev(fac[maxn - ],mod);
for(LL i = maxn - ;i >= ;--i){
inv[i] = inv[i + ] * (i + ) % mod;
//printf("inv[%d] == %lld\n",i,inv[i]);
}
}
LL C(int n,int m){
return ((fac[n] * inv[m]) % mod) * inv[n - m] % mod;
}
LL dfs(int l,int r){
//printf("now l == %d r == %d\n",l,r);
if(flag) return ;
if(l > r) return ; if(store[cnt].l != l || store[cnt].r != r){
flag = true;
return ;
}
node cur = store[cnt++];
int mid = cur.id;
LL lft = ,rht = ,c = ;
lft = dfs(l,mid - );
rht = dfs(mid + ,r);
c = C(r - l,mid - l);
//printf("c == %lld\n",c);
//printf("---> %lld\n",(lft * rht % mod) * c % mod);
return (lft * rht % mod) * c % mod;
} int main(){
int cas = ,n;
init();
while(scan_d(n)){
flag = false;
cnt = ;
for(int i = ;i <= n;++i) scan_d(store[i].l);
for(int i = ;i <= n;++i) scan_d(store[i].r),store[i].id = i;
sort(store + ,store + n + );
LL ans = dfs(,n);
printf("Case #%d: %lld\n",cas++,ans);
}
return ;
}

最新文章

  1. Android SDK Manager无法更新的解决[ 转]
  2. Twitter Bootstrap
  3. atitit.软件开发方法总结O6
  4. 谈谈JPA-04-JPA的常用API
  5. Exel 利用模板导出方法
  6. go之匿名字段
  7. 用Python实现gmail邮箱服务,实现两个邮箱之间的绑定(中)
  8. HDU 3584 Cube(三位树状数组)
  9. Redis4.0 Cluster — Centos7
  10. springboot启动流程
  11. go语言数据库操作,xorm框架
  12. centos7.4 python3.6 Anaconda3 的下安装tensorflow
  13. poj 3177 Redundant Paths(边双连通分量+缩点)
  14. (Review cs231n) The Gradient Calculation of Neural Network
  15. 使用Handlerf发送消息或使用Handler轮询时,报错IllegalStateException:This message is already in use.;
  16. KMP算法用JavaScript实现
  17. dubbo 接口初入门
  18. 项目Beta冲刺(团队)总结
  19. eclipse 设置文本模板中 insert variable... 函数 详解
  20. TS Stream 详解

热门文章

  1. 林大妈的JavaScript基础知识(一):JavaScript简史
  2. python 接口测试环境准备
  3. java抽奖思路
  4. 前端js性能优化的要点
  5. JDK的命令行工具系列 (三) jhat、jstack
  6. php 生成随机字符串,数字,大写字母,小写字母,特殊字符可以随意组合
  7. Starling 环形进度条实现
  8. 全球十大OTA 谁能有一席之地?
  9. MySQL InnoDB Cluster介绍
  10. PCB学习总结