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

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1934

听说会笛卡尔树的人这题都秒了啊……

参考:https://blog.csdn.net/vectorxj/article/details/79475244

首先题得看懂(我就是看题解才看懂题面的……),它告诉你对于i,我们有最大的(li,ri)使得这个区间内pi最小。

于是最小的数一定是(1,n)区间内的,设为pos,那么我们只需要递归处理(1,pos-1)和(pos+1,n)的即可。

当然我们的情况数要乘以给左区间的数的情况数。

中途如果出现各种无解情况直接返回0即可。

注意读入优化!

#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
struct fastio{
    static const int bs=1000000;
    char c(){
    static char buf[bs],*S=buf,*T=buf;
        if(S==T){
        T=(S=buf)+fread(buf,1,bs,stdin);
        if(S==T)return EOF;
    }
    return *S++;
    }
    int operator()(){
        int X=0;char ch=c();
    if(ch==EOF)return 0;
    while(!isdigit(ch))ch=c();
    while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=c();
    return X;
    }
}read;
const int N=1e6+5;
const int p=1e9+7;
inline int qpow(int k,int n){
    int res=1;
    while(n){
    if(n&1)res=(ll)res*k%p;
    k=(ll)k*k%p;n>>=1;
    }
    return res;
}
map<int,int>mp[N];
int n,cnt,l[N],r[N];
int jc[N],inv[N];
void init(int k){
    jc[0]=1;
    for(int i=1;i<=k;i++)jc[i]=(ll)jc[i-1]*i%p;
    inv[k]=qpow(jc[k],p-2);
    for(int i=k-1;i;i--)inv[i]=(ll)inv[i+1]*(i+1)%p;
    inv[0]=1;
}
inline int C(int a,int b){
    return (ll)jc[a]*inv[b]%p*inv[a-b]%p;
}
int work(int L,int R){
    if(L>R)return 1;
    int pos=mp[L][R];
    if(L==pos&&pos==R)return 1;
    if(pos<L||R<pos)return 0;
    return (ll)C(R-L,pos-L)*work(L,pos-1)%p*work(pos+1,R)%p;
}
int main(){
    init(1e6);
    while(n=read()){
    for(int i=1;i<=n;i++)mp[i].clear();
    for(int i=1;i<=n;i++)l[i]=read();
    for(int i=1;i<=n;i++)r[i]=read();
    bool flag=1;
    for(int i=1;i<=n;i++){
        if(mp[l[i]].count(r[i]))flag=0;
        mp[l[i]][r[i]]=i;
    }
    if(!flag)printf("Case #%d: 0\n",++cnt);
    else printf("Case #%d: %d\n",++cnt,work(1,n));
    }
    return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

posted @ 2018-06-13 10:46  luyouqi233  阅读(183)  评论(0编辑  收藏  举报