zoukankan      html  css  js  c++  java
  • BZOJ4756: [Usaco2017 Jan]Promotion Counting

    n<=100000的点权树,问每个点子树内有多少个比他大。

    方法一:区间第K大!……

    方法二:线段树合并,值为下标,每次把所有的孩子和自己合并起来,然后线段树中直接查找即可。

     1 #include<cstring>
     2 #include<cstdlib>
     3 #include<cstdio>
     4 //#include<assert.h>
     5 #include<math.h>
     6 #include<algorithm>
     7 //#include<iostream>
     8 using namespace std;
     9 
    10 int n;
    11 #define maxn 100011
    12 struct Edge{int to,next;}edge[maxn<<1];int first[maxn],le=2;
    13 void in(int x,int y) {Edge &e=edge[le];e.to=y;e.next=first[x];first[x]=le++;}
    14 int num[maxn],root[maxn];
    15 struct SMT
    16 {
    17     struct Node
    18     {
    19         int cnt;
    20         int l,r;
    21         int ls,rs;
    22         Node() {ls=rs=0;}
    23     }a[maxn*20];
    24     //值经过离散化成1~n 
    25     int size;
    26     SMT() {size=0;}
    27     void up(int x)
    28     {
    29         const int &p=a[x].ls,&q=a[x].rs;
    30         a[x].cnt=a[p].cnt+a[q].cnt;
    31     }
    32     void build(int &x,int L,int R,int pos)
    33     {
    34         x=++size;
    35         a[x].l=L;a[x].r=R;
    36         if (a[x].l==a[x].r)
    37         {
    38             a[x].cnt=1;
    39             a[x].ls=a[x].rs=0;
    40         }
    41         else
    42         {
    43             const int mid=(L+R)>>1;
    44             if (pos<=mid) build(a[x].ls,L,mid,pos),a[x].rs=0;
    45             else build(a[x].rs,mid+1,R,pos),a[x].ls=0;
    46             up(x);
    47         }
    48     }
    49     void build(int &x,int pos) {build(x,1,n,pos);}
    50     int query(int x,int k)
    51     {
    52         if (a[x].r<=k) return 0;
    53         if (a[x].l>k) return a[x].cnt;
    54         return query(a[x].ls,k)+query(a[x].rs,k);
    55     }
    56     int combine(int x,int y)
    57     {
    58         if (!x || !y) return x+y;
    59         a[x].ls=combine(a[x].ls,a[y].ls);
    60         a[x].rs=combine(a[x].rs,a[y].rs);
    61         up(x);
    62         return x;
    63     }
    64 }t;
    65 bool isdigit(char c) {return c>='0' && c<='9';}
    66 int qread()
    67 {
    68     char c;int s=0;while (!isdigit(c=getchar()));
    69     do s=s*10+c-'0'; while (isdigit(c=getchar()));return s;
    70 }
    71 int lisan[maxn];
    72 int ans[maxn];
    73 void dfs(int x)
    74 {
    75     t.build(root[x],num[x]);
    76     for (int i=first[x];i;i=edge[i].next)
    77     {
    78         const Edge &e=edge[i];
    79         dfs(e.to);
    80         root[x]=t.combine(root[x],root[e.to]);
    81     }
    82     ans[x]=t.query(root[x],num[x]);
    83 }
    84 int main()
    85 {
    86     n=qread();
    87     for (int i=1;i<=n;i++) lisan[i]=num[i]=qread();
    88     sort(lisan+1,lisan+1+n);
    89     for (int i=1;i<=n;i++) num[i]=lower_bound(lisan+1,lisan+1+n,num[i])-lisan;
    90     for (int i=2,x;i<=n;i++) x=qread(),in(x,i);
    91     dfs(1);
    92     for (int i=1;i<=n;i++) printf("%d
    ",ans[i]);
    93     return 0;
    94 }
    View Code
  • 相关阅读:
    站立会议第四天
    站立会议第三天
    站立会议第二天
    站立会议第一天
    团队项目估算
    团队计划会议
    《人月神话》阅读笔记01
    《构建之法》阅读笔记06
    微软买书问题
    找水王2
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7725443.html
Copyright © 2011-2022 走看看