HDU 6044--Limited Permutation(搜索+组合数+逆元)
Given the positive integers n, (li,ri) (1≤i≤n), 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.
For each test case:
The first line contains one positive integer n, satisfying 1≤n≤106.
The second line contains n positive integers l1,l2,⋯,ln, satisfying 1≤li≤i for each 1≤i≤n.
The third line contains n positive integers r1,r2,⋯,rn, satisfying i≤ri≤n for each 1≤i≤n.
It's guaranteed that the sum of n in all test cases is not larger than 3⋅106.
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.
现在给了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 <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL;
const int N=1e6+;
const LL mod=1e9+;
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 = ;
sz = fread(buf, , MX, stdin);
}
inline bool read(int &t) {
while(c < sz && buf[c] != '-' && (buf[c] < '' || buf[c] > '')) c++;
if(c >= sz) return false;
bool flag = ; if(buf[c] == '-') flag = , c++;
for(t = ; c < sz && '' <= buf[c] && buf[c] <= ''; c++) t = t * + buf[c] - '';
if(flag) t = -t;
return true;
}
} void Init(){
fac[] = Inv[] = fac[] = Inv[] = ;
for(int i=; i<N; i++) fac[i] = fac[i-] * i % mod;
for(int i=; i<N; i++) Inv[i] = (mod - mod / i) * Inv[mod % i] % mod;
for(int i=; i<N; i++) Inv[i] = Inv[i] * Inv[i-] % mod;
}
LL C(LL n, LL m){
LL ans = fac[n] * Inv[m] % mod* Inv[n-m] %mod;
return ans;
}
int ii;
struct Node{
int l,r;
int id;
}a[N];
bool cmp(const Node s1,const Node s2)
{
if(s1.l==s2.l) return s1.r>s2.r;
return s1.l<s2.l;
}
LL dfs(int L,int R)
{
if(a[ii].l!=L || a[ii].r!=R) return ;
int m=a[ii++].id;
LL fL=,fR=;
if(L<=m-) fL=dfs(L,m-);
if(m+<=R) fR=dfs(m+,R);
LL c=C(R-L,m-L);
return fL*fR%mod*c%mod;
}
int main()
{
Init();
int n,Case=;
IO::begin();
while(IO::read(n))
{
for(int i=;i<=n;i++) IO::read(a[i].l);
for(int i=;i<=n;i++) IO::read(a[i].r), a[i].id = i;
sort(a+,a+n+,cmp);
ii=;
LL ans=dfs(,n);
printf("Case #%d: %lld\n",Case++,ans);
}
return ;
}
HDU 6044--Limited Permutation(搜索+组合数+逆元)的更多相关文章
- HDU 6044 - Limited Permutation | 2017 Multi-University Training Contest 1
研究一下建树 : /* HDU 6044 - Limited Permutation [ 读入优化,笛卡尔树 ] | 2017 Multi-University Training Contest 1 ...
- HDU 6044 Limited Permutation 读入挂+组合数学
Limited Permutation Problem Description As to a permutation p1,p2,⋯,pn from 1 to n, it is uncomplica ...
- HDU 6044 Limited Permutation(搜索+读入优化)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6044 [题目大意] 给出两个序列li,ri,现在要求构造排列p,使得对于区间[li,ri]来说, ...
- hdu 6044 : Limited Permutation (2017 多校第一场 1012) 【输入挂 组合数学】
题目链接 参考博客: http://blog.csdn.net/jinglinxiao/article/details/76165353 http://blog.csdn.net/qq_3175920 ...
- 【HDU 5698】瞬间移动(组合数,逆元)
x和y分开考虑,在(1,1)到(n,m)之间可以选择走i步.就需要选i步对应的行C(n-2,i)及i步对应的列C(m-2,i).相乘起来. 假设$m\leq n$$$\sum_{i=1}^{m-2} ...
- Harvest of Apples (HDU多校第四场 B) (HDU 6333 ) 莫队 + 组合数 + 逆元
题意大致是有n个苹果,问你最多拿走m个苹果有多少种拿法.题目非常简单,就是求C(n,0)+...+C(n,m)的组合数的和,但是询问足足有1e5个,然后n,m都是1e5的范围,直接暴力的话肯定时间炸到 ...
- 2016 ACM/ICPC Asia Regional Shenyang Online 1003/HDU 5894 数学/组合数/逆元
hannnnah_j’s Biological Test Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K ...
- HDU - 6143 Killer Names(dp记忆化搜索+组合数)
题意:从m种字母中选取字母组成姓名,要求姓和名中不能有相同的字母,姓和名的长度都为n,问能组成几种不同的姓名. 分析: 1.从m种字母中选取i种组成姓,剩下m-i种组成名. 2.i种字母组成长度为n的 ...
- Problem B. Harvest of Apples(杭电2018年多校+组合数+逆元+莫队)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6333 题目: 题意:求C(n,0)+C(n,1)+……+C(n,m)的值. 思路:由于t和n数值范围太 ...
随机推荐
- java基础 ----- 选择结构
--------- 流程控制 ------ 流程图 ------ 基本的 if 选择结构 import java.util.Scanner; public class GetPr ...
- jq怎么给图片绑定上传文件按钮
html代码 <img src="/img/zhengmian.png" alt="" class="file1"> <i ...
- 254. Factor Combinations 返回所有因数组合
[抄题]: Numbers can be regarded as product of its factors. For example, 8 = 2 x 2 x 2; = 2 x 4. Write ...
- jdk1.8 HashMap的实现
在了解HashMap之前,我们先进行位运算知识的补充 1.Java 位运算:(都是二进制的运算) << :相当于乘以2的倍数 --->1<<4 =1*2*2*2*2 ...
- pip 国内源 配置
pip 国内源 配置 2017年12月09日 16:05:20 阅读数:183 最近使用 pip 安装包,动辄十几 k 甚至几 k 的下载速度,确实让人安装的时候心情十分不好.所以还是要给 pip 换 ...
- 循序渐进VBA EXCEL数据操作小实例
1 向指定单元格区域内写入数据 Sub example1() ) arr() = Array("A", "B", "C", "D& ...
- Win10电脑系统使用技巧
现如今,电脑已经成为我们不可或缺的伙伴,陪伴着我们的工作.娱乐和生活,而Windows10在大家使用的电脑中占据了大多数,但是很多的小伙伴对它的许多功能并不真正了解,今天小编就带大家了解一下这些技巧, ...
- python爬虫笔记
1.抓取网页并保存到txt中.解决控制台乱码问题 #_*_coding:utf-8_*_ import urllib2 response = urllib2.urlopen('http://hws.m ...
- Android 软件管理工具类Utils
Android 软件管理工具类Utils /** * Created by uilubo on 2015/9/30. * 工具类 */ public class Utils { public stat ...
- modal 永久移除遮盖层
样式中直接加入: .modal-backdrop { opacity: 0 !important; filter: alpha(opacity=0) !important;}