• BZOJ 4756 Promotion Counting


    用线段树合并水了这题。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxn 100500
    #define maxe 200500
    using namespace std;
    int n,x,p[maxn],g[maxn],hash[maxn],nume=1,len=0,tot=0,ans[maxn];
    int ls[maxn*20],rs[maxn*20],sum[maxn*20],root[maxn];
    struct edge
    {
        int v,nxt;
    }e[maxe];
    int read()
    {
        char ch;int f=1,data=0;
        while (ch<'0' || ch>'9')
        {
            if (ch=='-') f=-1;
            ch=getchar();
        }
        while (ch>='0' && ch<='9')
        {
            data=data*10+ch-'0';
            ch=getchar();
        }
        return data*f;
    }
    void addedge(int u,int v)
    {
        e[++nume].v=v;
        e[nume].nxt=g[u];
        g[u]=nume;
    }
    void pushup(int now) {sum[now]=sum[ls[now]]+sum[rs[now]];}
    void build(int &now,int left,int right,int pos)
    {
        now=++tot;
        if (left==right) {sum[now]=1;return;}
        int mid=(left+right)>>1;
        if (pos<=mid) build(ls[now],left,mid,pos);
        else build(rs[now],mid+1,right,pos);
        pushup(now);
    }
    int ask(int now,int left,int right,int l,int r)
    {
        if (!now) return 0;
        if ((left==l) && (right==r)) return sum[now];
        int mid=(left+right)>>1;
        if (r<=mid) return ask(ls[now],left,mid,l,r);
        else if (l>=mid+1) return ask(rs[now],mid+1,right,l,r);
        else return ask(ls[now],left,mid,l,mid)+ask(rs[now],mid+1,right,mid+1,r);
    }
    int merge(int x,int y)
    {
        if (!x) return y;
        if (!y) return x;
        ls[x]=merge(ls[x],ls[y]);rs[x]=merge(rs[x],rs[y]);
        pushup(x);
        return x;
    }
    void dfs(int now,int fath)
    {
        int ret=0;
        for (int i=g[now];i;i=e[i].nxt)
        {
            int v=e[i].v;
            if (v==fath) continue;
            dfs(v,now);
            ret+=ask(root[v],1,n,p[now]+1,n);
            root[now]=merge(root[now],root[v]);
        }
        ans[now]=ret;
    }
    int main()
    {
        n=read();
        for (int i=1;i<=n;i++)
        {
            p[i]=read();
            hash[++len]=p[i];
        }
        sort(hash+1,hash+len+1);len=unique(hash+1,hash+len+1)-hash-1;
        for (int i=1;i<=n;i++) p[i]=lower_bound(hash+1,hash+len+1,p[i])-hash;
        for (int i=2;i<=n;i++) 
        {
            x=read();
            addedge(i,x);addedge(x,i);
        }    
        for (int i=1;i<=n;i++) build(root[i],1,n,p[i]);
        dfs(1,1);
        for (int i=1;i<=n;i++) printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    ES6新特性:使用export和import实现模块化
    常见Linux/Unix开发辅助命令什锦
    Spark高速上手之交互式分析
    Lua中的元表与元方法
    explicit 构造函数
    【排序】基数排序(计数排序、桶排序)
    拓展训练—心得体会
    poj3411--Paid Roads(bfs+状压)
    点击单选button后的文字就可以选定相应单选button
    hdu 2349 最小生成树
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/6360339.html
Copyright © 2020-2023  润新知