笛卡尔树 + 虚树

hdu6305

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+50;
const ll mod=1e9+7;
int a[maxn],l[maxn],r[maxn],sz[maxn];
ll inv[maxn];
ll ans;
stack<int>s;
void dfs(int u){
    sz[u]=1;
    if(l[u])
        dfs(l[u]),sz[u]+=sz[l[u]];
    if(r[u])
        dfs(r[u]),sz[u]+=sz[r[u]];
    ans=ans*inv[sz[u]]%mod;
}
int main(){
    inv[0]=inv[1]=1;
    for(int i=2;i<=1e6;i++)
        inv[i]=1LL*inv[mod%i]*(mod-mod/i)%mod;
    int t;
    cin>>t;
    while(t--){
        int n,rt;
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            l[i]=r[i]=0;
            while(!s.empty()&&a[i]>a[s.top()])
                l[i]=s.top(),s.pop();
            if(!s.empty())
                r[s.top()]=i;
            s.push(i);
        }
        while(!s.empty())
            rt=s.top(),s.pop();
        ans=1LL*inv[2]*n;
        dfs(rt);
        cout<<ans<<endl;
    }
    return 0;
}

2019牛客暑期多校训练营(第一场)(A)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+50;
const ll mod=1e9+7;
int l[maxn][2],r[maxn][2],rt[2];
int a[maxn],b[maxn];
stack<int>st;
bool dfs(int u){
    if(l[u][0]!=l[u][1]||r[u][0]!=r[u][1])
        return false;
    int ok=1;
    if(l[u][0])ok&=dfs(l[u][0]);
    if(r[u][0])ok&=dfs(r[u][0]);
    return ok;
}
bool check(int mid){
    for(int i=1;i<=mid;i++){
        l[i][0]=r[i][0]=0;
        while(!st.empty()&&a[i]<a[st.top()]){
            l[i][0]=st.top();
            st.pop();
        }
        if(!st.empty())r[st.top()][0]=i;
        st.push(i);
    }
    while(!st.empty())
        rt[0]=st.top(),st.pop();

    for(int i=1;i<=mid;i++){
        l[i][1]=r[i][1]=0;
        while(!st.empty()&&b[i]<b[st.top()]){
            l[i][1]=st.top();
            st.pop();
        }
        if(!st.empty())r[st.top()][1]=i;
        st.push(i);
    }
    while(!st.empty())
        rt[1]=st.top(),st.pop();
    if(rt[0]!=rt[1])return 0;
    return dfs(rt[0]);
}
int main(){
    int n;
    while(cin>>n){
        for(int i=1;i<=n;i++)cin>>a[i];
        for(int j=1;j<=n;j++)cin>>b[j];
        int l=1,r=n,ans;
        while(l<=r){
            int mid=(l+r)/2;
            if(check(mid)){
                ans=mid;
                l=mid+1;
            }
            else r=mid-1;
        }
        cout<<ans<<endl;
    }
    return 0;
}

posted @ 2019-07-23 17:48  luowentao  阅读(154)  评论(0编辑  收藏  举报