• 笛卡尔树 + 虚树



    ayout: post
    title: 笛卡尔树 + 虚树
    author: "luowentaoaa"
    catalog: true
    mathjax: true
    tags:

    • 单调栈

    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;
    }
    
    
  • 相关阅读:
    第002篇 深入体验C#项目开发(一)
    C#编程打字指法练习
    第001篇——C#学习计划开启
    2020杭电多校第一场(待更新)
    LeetCode双周赛11
    LeetCode双周赛10
    LeetCode Weekly 156
    NOIP模板复习(4)区间操作之莫队算法,树状数组,线段树
    NOIP模板复习(3) 最短路三巨头Floyd,Dijkstra与SPFA
    NOIP模板复习(2) LCA的三种解法
  • 原文地址:https://www.cnblogs.com/luowentao/p/11233365.html
Copyright © 2020-2023  润新知