【51nod】1934 受限制的排列
题解
这题还要判无解真是难受……
我们发现我们肯定能确定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 受限制的排列的更多相关文章
- 51nod 1934 受限制的排列——笛卡尔树
题目:http://www.51nod.com/Challenge/Problem.html#!#problemId=1934 根据给出的信息,可以递归地把笛卡尔树建出来.一个点只应该有 0/1/2 ...
- 51NOD 1934:受限制的排列——题解
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1934 听说会笛卡尔树的人这题都秒了啊…… 参考:https://blog ...
- 51nod1934:受限制的排列 (分治+组合数)
对于一个 11 到 nn 的排列 p1,p2,⋯,pnp1,p2,⋯,pn ,我们可以轻松地对于任意的 1≤i≤n1≤i≤n 计算出 (li,ri)(li,ri) ,使得对于任意的 1≤L ...
- 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 ...
- 胡小兔的OI日志3 完结版
胡小兔的 OI 日志 3 (2017.9.1 ~ 2017.10.11) 标签: 日记 查看最新 2017-09-02 51nod 1378 夹克老爷的愤怒 | 树形DP 夹克老爷逢三抽一之后,由于采 ...
- 51nod 1364 最大字典序排列(线段树)
1364 最大字典序排列基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 给出一个1至N的排列,允许你做不超过K次操作,每次操作可以将相邻的两个数交换,问能够得到的字 ...
- 51nod 1020 逆序排列
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1020 题意: 思路: 一开始用了三重循环... 设f(n,k)表示n个数 ...
- 51Nod 1250 排列与交换
Description 统计 \(1...n\) 的排列,恰好进行 \(k\) 次相邻交换和至多进行 \(k\) 次交换生成的不同的序列个数. Sol DP. 好妙的题啊... 首先看第一个问题. 对 ...
- 51nod 1020 逆序排列 DP
在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数. 如2 4 3 1中,2 1,4 3,4 1,3 1是逆序 ...
随机推荐
- C# 在程序中控制IIS服务或应用程序池关闭重启
//停止IIS服务 ServiceController sc = new ServiceController("iisadmin"); if(sc.Status=ServiceCo ...
- day21 数据库(DataBase)
1.数据库由多张表组成,一张表就是一个实体. 2.表的列就是属性的值,行就是一个个具体的对象的属性值. primary key主键:1.非空.2.不能修改(定好不变).3.业务无关. 作用:在表中具体 ...
- 缓存失效策略(FIFO,LRU,LFU)
当缓存需要被清理时(比如空间占用已经接近临界值了),需要使用某种淘汰算法来决定清理掉哪些数据.常用的淘汰算法有下面几种: 1. FIFO:First In First Out,先进先出.判断被存储的时 ...
- 科学计算三维可视化---TVTK入门(创建和显示三维对象)
一:创建一个基本的三维对象 (一)长方体操作 traits:就是TVTK对象的属性 (1)对象属性操作 >>> from tvtk.api import tvtk >>& ...
- 【Linux】VirtualBox安装ubuntu排错LowGraphic
在Oracle的VirtualBox虚拟机上,安装Ubuntu后,提示了如下图这样的 错误 The system is running in low-graphics mode 在网上搜,有多种解答方 ...
- 20145234黄斐《Java程序设计》第七周
教材学习内容总结 第十二章部分 - Lambda 认识Lambda语法 Lambda去可以重复,符合DRY原则,而且Lambda表达式可读性更好,操作更简单 匿名类型最大的问题就在于其冗余的语法,la ...
- HDU 1259 ZJUTACM
解题报告:就用了一个swap函数就行了. #include<cstdio> #include<iostream> int main() { int x,y,T,n; scanf ...
- HDU 2087 剪花布条 (KMP 不允许重叠的匹配)
题目链接 Problem Description 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢? Inp ...
- Go语言知识点笔记
golang的花括号: 在go中,继承了C系的花括号作为一个作用域块的包含范围指示,但不同于C/C++中花括号位置可任意摆放,go要求“ { ”必须在右侧(一行代码尾部),不能单独另起一行.类似Pyt ...
- JavaScript中函数参数的值传递和引用传递
结论: 对于数字.字符串等基本类型变量,是将它们的值传递给了函数参数,函数参数的改变不会影响函数外部的变量. 对于数组和对象等是将对象(数组)的变量的值传递给了函数参数,这个变量保存的指向对象(数组) ...