zoukankan      html  css  js  c++  java
  • LOJ#2665 树的计数

    题意:给你DFS序和BFS序,求树的期望高度。

    解:先分析性质。

    考虑到BFS序是分层的,DFS序的子树是一段,那么我们遍历BFS序并在DFS序上标记对应点的话,就会发现BFS序每一层都会把若干棵子树每个都分成若干个小子树,且换层的时候一定会是DFS序上第一个非空位置。

    设每个点的期望深度为hi,那么就是要求BFS序最后一个点的h。考虑每个点的深度怎么算。如果当前点不是新一层的开头,那么它的h一定等于他在BFS序前面一个点的深度。如果是开头,那么就要等于它父亲的深度 + 1,我们可以在DFS序上把每个点的子树染色以查明该点的父亲。如果这两种情况都有可能,那么h就是这两种情况的平均数。

    考虑什么时候只可能是一种情况。

    当这个点在DFS序上的位置前于BFS序上前一个点在DFS序上的位置的时候,当前点一定是新一层的开头。

    当这个点在DFS序上的位置后与BFS序上前一个点在DFS序上的位置的时候:如果这个点和BFS上前一个点在DFS序上的位置不相邻,那么这两个点一定在同一层。

    相邻的时候,如果当前点在DFS序的前面还有空位,那么一定在同一层。否则考虑这个子树后面还有没有空位,如果有也一定在同一层,因为要换层的话一定要把后面的每个都走一遍。

    实现的时候就用线段树维护颜色和区间和。

      1 #include <bits/stdc++.h>
      2 
      3 const int N = 200010;
      4 
      5 int col[N << 2], sum[N << 2];
      6 int d[N], b[N], pos[N];
      7 double h[N];
      8 
      9 inline void pushdown(int o) {
     10     if(!col[o]) return;
     11     col[o << 1] = col[o << 1 | 1] = col[o];
     12     col[o] = 0;
     13     return;
     14 }
     15 
     16 void add(int p, int l, int r, int o) {
     17     if(l == r) {
     18         sum[o] = 1;
     19         return;
     20     }
     21     int mid = (l + r) >> 1;
     22     if(p <= mid) add(p, l, mid, o << 1);
     23     else add(p, mid + 1, r, o << 1 | 1);
     24     sum[o] = sum[o << 1] + sum[o << 1 | 1];
     25     return;
     26 }
     27 
     28 int getSum(int L, int R, int l, int r, int o) {
     29     if(L <= l && r <= R) return sum[o];
     30     int mid = (l + r) >> 1, ans = 0;
     31     if(L <= mid) ans += getSum(L, R, l, mid, o << 1);
     32     if(mid < R) ans += getSum(L, R, mid + 1, r, o << 1 | 1);
     33     return ans;
     34 }
     35 
     36 void change(int L, int R, int v, int l, int r, int o) {
     37     if(L <= l && r <= R) {
     38         col[o] = v;
     39         return;
     40     }
     41     pushdown(o);
     42     int mid = (l + r) >> 1;
     43     if(L <= mid) change(L, R, v, l, mid, o << 1);
     44     if(mid < R) change(L, R, v, mid + 1, r, o << 1 | 1);
     45     return;
     46 }
     47 
     48 int ask(int p, int l, int r, int o) {
     49     if(l == r) return col[o];
     50     int mid = (l + r) >> 1;
     51     pushdown(o);
     52     if(p <= mid) return ask(p, l, mid, o << 1);
     53     else return ask(p, mid + 1, r, o << 1 | 1);
     54 }
     55 
     56 int getKth(int k, int l, int r, int o) {
     57     if(l == r) {
     58         return r + (k > sum[o]);
     59     }
     60     int mid = (l + r) >> 1;
     61     if(k <= sum[o << 1]) {
     62         return getKth(k, l, mid, o << 1);
     63     }
     64     else {
     65         return getKth(k - sum[o << 1], mid + 1, r, o << 1 | 1);
     66     }
     67 }
     68 
     69 int main() {
     70 
     71     int n;
     72     scanf("%d", &n);
     73     for(int i = 1; i <= n; i++) {
     74         scanf("%d", &d[i]);
     75         pos[d[i]] = i;
     76     }
     77     for(int i = 1; i <= n; i++) {
     78         scanf("%d", &b[i]);
     79     }
     80     /// h[1] = 1
     81     for(int i = 1; i <= n; i++) {
     82         /// b[i] in pos[b[i]]
     83         int p = pos[b[i]], lastp = pos[b[i - 1]];
     84         add(p, 1, n, 1);
     85         int s = getSum(1, p, 1, n, 1);
     86         int ed = getKth(s + 1, 1, n, 1) - 1;
     87         /// [p, ed]
     88         if(i == 1) {
     89             h[b[i]] = 1;
     90         }
     91         else if(p == lastp + 1 && s == p && (ed < n ? getSum(ed + 1, n, 1, n, 1) : 0) == n - ed) {
     92             int fr = ask(p, 1, n, 1);
     93             if(fr != d[1]) h[b[i]] = (h[fr] + 1 + h[b[i - 1]]) / 2;
     94             else h[b[i]] = h[fr] + 1;
     95         }
     96         else if(p < lastp) { /// new line
     97             int fr = ask(p, 1, n, 1);
     98             h[b[i]] = h[fr] + 1;
     99         }
    100         else {
    101             h[b[i]] = h[b[i - 1]];
    102         }
    103         change(p, ed, b[i], 1, n, 1);
    104     }
    105 
    106     printf("%.3f
    ", h[b[n]]);
    107     return 0;
    108 }
    AC代码
  • 相关阅读:
    IXmlSerializable With WCFData Transfer in Service Contracts
    Difference Between XmlSerialization and BinarySerialization
    Using XmlSerializer (using Attributes like XmlElement , XmlAttribute etc ) Data Transfer in Service Contracts
    Introducing XML Serialization
    Version Tolerant Serialization
    Which binding is bestWCF Bindings
    Data Transfer in Service Contracts
    DataContract KnownTypeData Transfer in Service Contracts
    Using the Message ClassData Transfer in Service Contracts
    DataContract POCO SupportData Transfer in Service Contracts
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10775260.html
Copyright © 2011-2022 走看看