题解

这题还要判无解真是难受……

我们发现我们肯定能确定1的位置,1左右的两个区间是同理的可以确定出最小值的位置

我们把区间最小值看成给一个区间+1,构建出笛卡尔树,就求出了每一次取最小值和最小值左右的区间大小

然后就相当于左右子树的排列方式,乘上把左右子树那么多个元素选出左子树个数和右子树个数那么多的方案数,是个普通的组合数

判无解从根开始,要求根的区间是[1,N],左右区间是[1,rt-1][rt + 1,R]递归判下去就好

复杂度\(O(n)\)

但是跑得奇慢无比= =,我脑子一抽把数组改成两倍居然过了。。。卡着时限过的。。。不想写fread(懒.jpg)

代码

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define enter putchar('\n')
#define space putchar(' ')
#define MAXN 2000005
//#define ivorysi
using namespace std;
typedef long long int64;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {putchar('-');x = -x;}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
const int MOD = 1000000007; int N;
int L[MAXN],R[MAXN],S[MAXN],fac[MAXN],inv[MAXN],invfac[MAXN],lc[MAXN],rc[MAXN],rt;
int sta[MAXN],top;
int inc(int a,int b) {
return a + b >= MOD ? a + b - MOD : a + b;
}
int mul(int a,int b) {
return 1LL * a * b % MOD;
}
int C(int n,int m) {
if(n < m) return 0;
return mul(mul(fac[n],invfac[m]),invfac[n - m]);
}
bool check(int u,int fa,int l,int r) {
if(!u && l <= r) return false;
else if(!u) return true;
if(L[u] != l || R[u] != r) return false;
if(S[u] == fa + 1) {
return check(lc[u],S[u],l,u - 1) && check(rc[u],S[u],u + 1,r);
}
else return false;
}
int dfs(int u,int L,int R) {
if(!u) return 1;
return mul(mul(dfs(lc[u],L,u - 1),dfs(rc[u],u + 1,R)),C(R - L,u - L));
}
void Init() {
for(int i = 1 ; i <= N ; ++i) {lc[i] = rc[i] = 0;S[i] = 0;read(L[i]);}
for(int i = 1 ; i <= N ; ++i) {read(R[i]);S[L[i]]++;S[R[i] + 1]--;}
top = 0;int k;
for(int i = 1 ; i <= N ; ++i) {
S[i] += S[i - 1];
if(S[i] == 1) {rt = i;}
k = top;
while(k >= 1 && S[sta[k]] > S[i]) --k;
if(k + 1 <= top) lc[i] = sta[k + 1];
if(k) rc[sta[k]] = i;
top = k;
sta[++top] = i;
}
}
void Solve() {
if(!check(rt,0,1,N)) {out(0);enter;return;}
out(dfs(rt,1,N));enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
int cnt = 0;
fac[0] = 1;
for(int i = 1 ; i <= 1000000 ; ++i) fac[i] = mul(fac[i - 1],i);
inv[0] = inv[1] = 1;
for(int i = 2 ; i <= 1000000 ; ++i) inv[i] = mul(inv[MOD % i],MOD - MOD / i);
invfac[0] = 1;
for(int i = 1 ; i <= 1000000 ; ++i) invfac[i] = mul(invfac[i - 1],inv[i]);
while(scanf("%d",&N) != EOF) {
++cnt;
printf("Case #%d: ",cnt);
Init();
Solve();
}
}

不能再颓了!还有34天就NOI了!

时间太慢了,但是我又怕它太快了

【51nod】1934 受限制的排列的更多相关文章

  1. 51nod 1934 受限制的排列——笛卡尔树

    题目:http://www.51nod.com/Challenge/Problem.html#!#problemId=1934 根据给出的信息,可以递归地把笛卡尔树建出来.一个点只应该有 0/1/2 ...

  2. 51NOD 1934:受限制的排列——题解

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1934 听说会笛卡尔树的人这题都秒了啊…… 参考:https://blog ...

  3. 51nod1934:受限制的排列 (分治+组合数)

    对于一个  11 到  nn 的排列  p1,p2,⋯,pnp1,p2,⋯,pn ,我们可以轻松地对于任意的  1≤i≤n1≤i≤n 计算出  (li,ri)(li,ri) ,使得对于任意的  1≤L ...

  4. 51nod 1296 有限制的排列(DP)

    对于一个i,如果要比邻居大,那么i比i-1大,i+1比i小,比邻居小同理.设v[i]=0表示i与i-1的关系无限制,v[i]=1表示a[i-1]>a[i],v[i]=2表示a[i-1]<a ...

  5. 胡小兔的OI日志3 完结版

    胡小兔的 OI 日志 3 (2017.9.1 ~ 2017.10.11) 标签: 日记 查看最新 2017-09-02 51nod 1378 夹克老爷的愤怒 | 树形DP 夹克老爷逢三抽一之后,由于采 ...

  6. 51nod 1364 最大字典序排列(线段树)

    1364 最大字典序排列基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 给出一个1至N的排列,允许你做不超过K次操作,每次操作可以将相邻的两个数交换,问能够得到的字 ...

  7. 51nod 1020 逆序排列

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1020 题意: 思路: 一开始用了三重循环... 设f(n,k)表示n个数 ...

  8. 51Nod 1250 排列与交换

    Description 统计 \(1...n\) 的排列,恰好进行 \(k\) 次相邻交换和至多进行 \(k\) 次交换生成的不同的序列个数. Sol DP. 好妙的题啊... 首先看第一个问题. 对 ...

  9. 51nod 1020 逆序排列 DP

    在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数. 如2 4 3 1中,2 1,4 3,4 1,3 1是逆序 ...

随机推荐

  1. zz 启动Matlab提示Microsoft Visual C++ 2005 Redistributable存在问题问题

    帮助领导搞Matlab 2010a 绿色版; 领导把绿色版的文件夹挪了一下位置 (领导就是领导,做什么都按照自己的想当然的想法做) 然后, 脆弱的绿色版Matlab 2010a Portable就罢工 ...

  2. IntelliJ IDEA连接cvs超时Error refreshing view: Timeout while trying to connect to host

    在使用IntelliJ IDEA连接cvs的时候,有时会报超时错误: Error refreshing view: Timeout while trying to connect to host: 1 ...

  3. c# net 使用反射为对象赋值

    public T Bson2T(MongoDB.Bson.BsonDocument bson) { T t = default(T); //获取T类中的所有属性 PropertyInfo[] Tpro ...

  4. Centos7 设置静态IP后重启网络服务出错

    systemctl restart networkJob for network.service failed because the control process exited with erro ...

  5. [csp-201403-3]命令行选项

    #include<bits/stdc++.h> //#include <sstream> // if want to use stringstream using namesp ...

  6. 写一个shell脚本利用wget抓取股票历史数据

    今天,大数据部老大交给我一项任务——抓取股票历史数据.于是乎,我自行在网上找了一下,发现wget真真是一个非常强大的linux下载工具.我已经被深深震撼到了.下面叙述今天的一些过程,还是比较坎坷的. ...

  7. ECMAScript 6中的var,let,const

    var的变量提升 console.log(a); //输出undefined ; 他的实际执行顺序是: var a: console.log(a); a= 这就是var的变量提升 const命令的用法 ...

  8. Python练习-天已经亮了计算器也终于完成了

    # 编辑者:闫龙 import re #导入re模块(正则表达式) calc2 = "1-2*((60-30+(-40/52)*(9-2*5/3+7/3*-99/4*2998+10*568/ ...

  9. python作业ATM(第五周)

    作业需求: 额度 15000或自定义. 实现购物商城,买东西加入 购物车,调用信用卡接口结账. 可以提现,手续费5%. 支持多账户登录. 支持账户间转账. 记录每月日常消费流水. 提供还款接口. AT ...

  10. python学习之argparse模块的使用

    以下内容主要来自:http://wiki.jikexueyuan.com/project/explore-python/Standard-Modules/argparse.html argparse ...