HDU6044-Limited Permutation(fread挂&&阶乘求逆元&&组合数)
2017-08-03 10:56
435 查看
Limited Permutation
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072K (Java/Others)
Total Submission(s): 1779 Accepted Submission(s): 482
Problem Description
As to a permutation p1,p2,⋯,pn from 1 to n,
it is uncomplicated for each 1≤i≤n to
calculate (li,ri) meeting
the condition that min(pL,pL+1,⋯,pR)=pi if
and only if li≤L≤i≤R≤ri for
each 1≤L≤R≤n.
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.
Input
The input contains multiple test cases.
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.
Output
For each test case, output "Case #x: y"
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
Source
2017 Multi-University Training Contest - Team 1
题意:给你n个区间,对于每个区间li,ri,当且仅当li<=L<=i<=R<=ri,满足pi=min(pL,pL+1,pL+2......pR-1,pR),问这样的p序列有几个
解题思路:可以知道对于区间(1,n)一定有一个最小值,所以一定有一个区间是(1,n)(用x表示),那么这个最小值把区间x分成两部分L和R ,所以一定存在为L和R的区间,如果不存在,那么输出0,令f(x)表示符合条件的区间x的排列数,那么f(x)=f(L)*f(R)*C(L+R,L) (C()表示组合数,L表示区间L的大小),只需要从区间(1,n)进行深搜即可,因为数据太大取模需要用到阶乘的逆元
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <functional>
using namespace std;
#define LL long long
const int INF = 0x3f3f3f3f;
const LL mod=1000000007;
int l[1000009],r[1000009];
LL ans;
LL mul[1000009],inv[1000009];
map<pair<int,int>,int> mp;
inline char get()
{
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
template <class T> inline bool read(T & x)
{
char ch=get();
if(ch==EOF) return false;
while (ch<'0' || ch>'9') ch = get();
x=ch-'0';
while ((ch = get()) >= '0'&&ch <= '9') x = x * 10 + ch - '0';
return true;
}
void init()
{
mul[0]=1;
for(int i=1; i<1000009; i++)
mul[i]=(mul[i-1]*i)%mod;
inv[0]=inv[1]=1;
for(int i=2; i<1000009; i++)
inv[i]=(LL)(mod-mod/i)*inv[mod%i]%mod;
for(int i=1; i<1000009; i++)
inv[i]=(inv[i-1]*inv[i])%mod;
}
LL C(int n,int m)
{
return mul
*inv[m]%mod*inv[n-m]%mod;
}
void dfs(int l,int r)
{
if(ans==0||r<l) return;
int k=mp[make_pair(l,r)];
if(k==0) {ans=0;return;}
if(l==r) return;
int len=r-l;
ans=(ans*C(len,k-l))%mod;
dfs(l,k-1);
dfs(k+1,r);
}
int main()
{
int n,cas=0;
init();
while(read(n))
{
mp.clear();
ans=1;
for(int i=1; i<=n; i++) read(l[i]);
for(int i=1; i<=n; i++)
{
read(r[i]);
mp[make_pair(l[i],r[i])]=i;
}
dfs(1,n);
printf("Case #%d: %lld\n",++cas,ans);
}
return 0;
}
相关文章推荐
- HDU6044 Limited Permutation (递归,预处理阶乘逆元)
- HDU 6044 Limited Permutation (组合数+逆元)
- HDU 6044 Limited Permutation(搜索+读入优化)
- Limited Permutation HDU - 6044 多校1
- 2017多校训练赛第一场 HDU 6044 Limited Permutation(虚建笛卡尔树+超级读入挂)
- HDU 6044 - Limited Permutation | 2017 Multi-University Training Contest 1
- HDU 6044 Limited Permutation 读入挂+组合数学
- 2017多校第一场 HDU 6044 Limited Permutation 思维,计数,DFS
- HDU 6044 Limited Permutation(递归)
- HDU - 6044 - Limited Permutation(fread输入挂+计数)
- HDU-6044 Limited Permutation(计数)
- HDU - 6044 Limited Permutation(dfs搜索+阶乘逆元预处理组合数+组合数学+输入输出挂)
- HDU 6044 Limited Permutation dfs 统计
- HDU 6044 Limited Permutation 想法
- HDU 1124 Factorial&&nyoj 84 阶乘的 0【数学】
- poj 1517 & hdu 1012 u Calculate e(简单阶乘)
- HDU 6044 Limited Permutation dfs + 组合数(读入挂)
- HDU 4349 组合数的奇数个数-杨辉三角&Lucas定理
- next_permutation & prev_permutation & hdu 1027 Ignatius and the Princess II
- HDU 5753 Permutation Bo 排列组合& 期望 多校3