博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 6044--Limited Permutation(搜索+组合数+逆元)
阅读量:5138 次
发布时间:2019-06-13

本文共 3076 字,大约阅读时间需要 10 分钟。

 

Problem Description
As to a permutation 
p1,p2,,pn from 1 to n, it is uncomplicated for each 1in to calculate (li,ri) meeting the condition that min(pL,pL+1,,pR)=pi if and only if liLiRri for each 1LRn.
Given the positive integers n(li,ri) (1in), you are asked to calculate the number of possible permutations p1,p2,,pn from 1 to n, meeting the above condition.
The answer may be very large, so you only need to give the value of answer modulo 109+7.
 

 

Input
The input contains multiple test cases.
For each test case:
The first line contains one positive integer 
n, satisfying 1n106.
The second line contains n positive integers l1,l2,,ln, satisfying 1lii for each 1in.
The third line contains n positive integers r1,r2,,rn, satisfying irin for each 1in.
It's guaranteed that the sum of n in all test cases is not larger than 3106.
Warm Tips for C/C++: input data is so large (about 38 MiB) that we recommend to use fread() for buffering friendly.
size_t fread(void *buffer, size_t size, size_t count, FILE *stream); // reads an array of count elements, each one with a size of size bytes, from the stream and stores them in the block of memory specified by buffer; the total number of elements successfully read is returned.
 

 

Output
For each test case, output "
Case #xy" in one line (without quotes), where 
x indicates the case number starting from 1 and y denotes the answer of corresponding case.
 

 

Sample Input
3
1 1 3
1 3 3
5
1 2 2 4 5
5 2 5 5 5
 

 

Sample Output
Case #1: 2 
Case #2: 3
 
题意:对于一个由1~n组成的排列称为合法的,必须满足这样的条件: 有n个(li,ri),对于每个 i 必须满足  min(pL,pL+1,⋯,pR)=pi if and only if li≤L≤i≤R≤ri for each 1≤L≤R≤n.

           现在给了n个(li,ri)求满足的排列有多少个。

 

思路:对于每个(li,ri),a[li-1]<a[i]>a[ri+1] ,并且a[i]是a[li]~a[ri]的最小值,那么可以想到:对于区间(1,n)一定有一个最小值,所以一定有一个区间是(1,n)(用X表示),那么这个最小值把区间X分成两部分U和V ,所以一定存在为U和V的区间,如果不存在,那么输出0,令f(X)表示符合条件的区间X的排列数,那么f(X)=f(U)*f(V)*C(U+V+1,U)   【注:C()表示组合数,U 表示区间U的大小】,所以我们只需要从区间(1,n)进行深搜即可,其中因为数据太大取模会用到逆元和组合数。

 

代码如下:

#include 
#include
#include
#include
#include
using namespace std;typedef long long LL;const int N=1e6+5;const LL mod=1e9+7;LL fac[N], Inv[N];/*int Scan()///输入外挂{ int res=0,ch,flag=0; if((ch=getchar())=='-') flag=1; else if(ch>='0'&&ch<='9') res=ch-'0'; while((ch=getchar())>='0'&&ch<='9') res=res*10+ch-'0'; return flag?-res:res;}*/namespace IO { const int MX = 4e7; //1e7占用内存11000kb char buf[MX]; int c, sz; void begin() { c = 0; sz = fread(buf, 1, MX, stdin); } inline bool read(int &t) { while(c < sz && buf[c] != '-' && (buf[c] < '0' || buf[c] > '9')) c++; if(c >= sz) return false; bool flag = 0; if(buf[c] == '-') flag = 1, c++; for(t = 0; c < sz && '0' <= buf[c] && buf[c] <= '9'; c++) t = t * 10 + buf[c] - '0'; if(flag) t = -t; return true; }}void Init(){ fac[0] = Inv[0] = fac[1] = Inv[1] = 1; for(int i=2; i
s2.r; return s1.l

 

转载于:https://www.cnblogs.com/chen9510/p/7258595.html

你可能感兴趣的文章
HDU 6370(并查集)
查看>>
BZOJ 1207(dp)
查看>>
对我来说,只有一件事情是重要的
查看>>
完整的Socket代码
查看>>
PE知识复习之PE的导入表
查看>>
POJ 3280 Cheapest Palindrome
查看>>
HDU 2076 夹角有多大(题目已修改,注意读题)
查看>>
Objective-C非正式协议与正式协议
查看>>
洛谷P3676 小清新数据结构题(动态点分治)
查看>>
SPOJ DQUERY D-query(主席树 区间不同数个数)
查看>>
八 Civil3d常用显示样式的编辑与创建 ----点标签样式2
查看>>
九校联考-DL24凉心模拟Day2T1 锻造(forging)
查看>>
生产阶段Webpack打包【基础打包】
查看>>
Cortex M3/M4 学习摘要(二)
查看>>
C#时间的味道——任时光匆匆我只在乎你
查看>>
(1)数据结构——线性表(数组)实现
查看>>
SpringMyBatis解析2-SqlSessionFactoryBean
查看>>
按照excel文档中的内容在当前cad图纸中自动排布实体
查看>>
Winform开发框架之图表报表在线设计器2-图表-SNF.EasyQuery项目--SNF快速开发平台3.3-Spring.Net.Framework...
查看>>
C#基础第八天-作业-设计类-面向对象方式实现两个帐户之间转账
查看>>