POJ 2201 &&HDU 6305 (笛卡尔树的应用)

POJ 2201

sol:笛卡尔树模板题,笛卡尔树的介绍可以参考 http://memphis.is-programmer.com/posts/46317.html

code:

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

typedef long long ll;
const int maxn = 1e5+10;

struct node{
    int k,id,p,val;
    int ch[2];
}tr[maxn];

bool cmp1(node& a,node& b){
    return a.k<b.k;
}

bool cmp2(node& a,node& b){
    return a.id<b.id;
}

int sta[maxn];
int top,rt;

int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d%d",&tr[i].k,&tr[i].val);
        tr[i].id = i;
    }
    sort(tr+1,tr+n+1,cmp1);
    for(int i=1;i<=n;i++){
        int rs = 0;
        while(top&&tr[sta[top]].val>tr[i].val){
            int u = sta[top];
            tr[u].ch[1] = rs;
            tr[rs].p = u;
            rs = u;
            tr[i].ch[0]=u;
            tr[u].p = i;
            top--;
        }
        if(top) {
            tr[sta[top]].ch[1]=i;
            tr[i].p = sta[top];
        }
        sta[++top]=i;
    }
    for(int i=1;i<=n;i++) {
        if(tr[i].p) tr[i].p = tr[tr[i].p].id;
        if(tr[i].ch[0]) tr[i].ch[0] = tr[tr[i].ch[0]].id;
        if(tr[i].ch[1]) tr[i].ch[1] = tr[tr[i].ch[1]].id;
    }
    sort(tr+1,tr+n+1,cmp2);
    puts("YES");
    for(int i=1;i<=n;i++){
        // cout<<i<<"  ------\n";
        printf("%d %d %d\n",tr[i].p,tr[i].ch[0],tr[i].ch[1]);
    }
    return 0;
}

HDU6305(多校第一场)题目链接

sol:

按照dls的讲解,RMQsimilar的实质就是两棵树的笛卡尔树同构。构建出A的笛卡尔树,那么随机生成的01序列与A同构的概率即为 \coprod_{i=1}^{n} \frac{1}{sz[i]} (sz[i]为笛卡尔树中以i为根的子树大小),根据直觉\sum_{i=1}^{n} b[i] = n/2,相乘即为答案。

code:

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

typedef long long ll;
const int maxn = 2e6+10;
const int mod = 1e9+7;

#define PII pair<int,int>
#define fi first
#define se second

ll inv[maxn];
int sta[maxn],ch[maxn][2];
int top,rt,n;
PII a[maxn];
ll ans;

void get_inv(){
    inv[1]=1;
    for(int i=2;i<maxn;i++) inv[i] = inv[mod%i]*(mod-mod/i)%mod;
}

void build(){
    rt = top = 0;
    for(int i=1;i<=n;i++){
        int rs = 0;
        while(top&&a[sta[top]]<a[i]){
            ch[sta[top]][1]= rs;
            rs = sta[top];
            ch[i][0] = sta[top];
            top--;
        }
        if(top) ch[sta[top]][1] = i;
        else rt = i;
        sta[++top]=i;
    }
}

int dfs(int u){
    if(u==0) return 0;
    int sz = 1;
    sz+=dfs(ch[u][0]);
    sz+=dfs(ch[u][1]);
    (ans*=inv[sz])%=mod;
    return sz;
}

int main(){
    get_inv();
    int T;
    scanf("%d",&T);
    while(T--){
        for(int i=1;i<=n;i++) ch[i][0]=ch[i][1]=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) {
            scanf("%d",&a[i].fi);
            a[i].se = -i;
        }
        build();
        ans = 1;
        dfs(rt);
        ans = ans*inv[2]%mod*n%mod;
        printf("%lld\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/oWuHen12/article/details/81233910
今日推荐