zoukankan      html  css  js  c++  java
  • 51nod1297 管理二叉树

    题目来源: HackerRank
    基准时间限制:3 秒 空间限制:131072 KB 分值: 640
    一个初始为空的二叉搜索树T,以及1到N的一个排列P: {a1, a2, ..., aN}。我们向这个二叉搜索树T添加这些数,从a1开始, 接下来是 a2, ..., 以aN结束。在每一个添加操作后,输出T上每对节点之间的距离之和。
    例如:4 7 3 1 8 2 6 5。最终的二叉树为:
     
           4
         /  
        3      7   
      /      /  
     1      6     8
         /
       2  5
     
    节点两两之间的距离和 = 6+5+5+4+3+2+1+5+4+4+3+2+1+4+3+3+2+1+3+2+2+1+2+1+1+2+1+3 = 76
    Input
    第1行:1个数N。(1 <= N <= 100000)
    第2 - N + 1行:每行1个数,对应排列的元素。(1 <= ai <= N)
    Output
    输出共N行,每行1个数,对应添加当前元素后,每对节点之间的距离之和。
    Input示例
    8
    4
    7
    3
    1
    8
    2
    6
    5
    Output示例
    0
    1
    4
    10
    20
    35
    52
    76

    树 规律题 动态点分治

    直接模拟建树妥妥被卡。

    分析一波可以发现,将一个点x添加进树的时候,在所有已有点中找到x的前驱和后继,x要么是前驱的右儿子,要么是前驱的左儿子。

    思考一下或者手玩一波会发现“前驱的右儿子”和“后继的左儿子“不会同时为空,所以要添加到哪里是确定的。

    我们可以离线操作,先将树建好,之后按顺序每次添加一个点,统计它到所有已有点的距离。

    剩下的部分显然是动态点分治模板题。

    写完WA了一半点,旁边czy说:“想必没有开LL”

    开了LL以后还有三个点WA,旁边czy说:“想必数组不够大”

    开大了数组就AC辣

    他真是个小天才!

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<cmath>
      6 #include<set>
      7 #define LL long long
      8 using namespace std;
      9 const int INF=0x3f3f3f3f;
     10 const int mxn=150010;
     11 int read(){
     12     int x=0,f=1;char ch=getchar();
     13     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     14     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
     15     return x*f;
     16 }
     17 struct edge{
     18     int v,nxt;
     19 }e[mxn<<1];
     20 int hd[mxn],mct=0;
     21 void add_edge(int u,int v){
     22     e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;return;
     23 }
     24 void insert(int u,int v){
     25     add_edge(u,v);add_edge(v,u);return;
     26 }
     27 int sz[mxn],mc[mxn],rot,smm;
     28 int dep[mxn],dis[mxn][23];
     29 int an[mxn][23];
     30 LL ans1[mxn],ans2[mxn],num[mxn];
     31 LL nowans;
     32 bool vis[mxn];
     33 void DFS_sz(int u,int fa){
     34     sz[u]=mc[u]=1;
     35     for(int i=hd[u];i;i=e[i].nxt){
     36         int v=e[i].v;;if(v==fa || vis[v])continue;
     37         DFS_sz(v,u);
     38         sz[u]+=sz[v];
     39         mc[u]=(sz[v]>mc[u])?sz[v]:mc[u];
     40     }
     41     mc[u]=max(mc[u],smm-sz[u]);
     42     if(mc[u]<mc[rot])rot=u;
     43     return;
     44 }
     45 void calc(int u,int fa,int ance,int dist){
     46     an[u][++dep[u]]=ance;
     47     dis[u][dep[u]]=dist;
     48     for(int i=hd[u];i;i=e[i].nxt){
     49         int v=e[i].v;
     50         if(v==fa || vis[v])continue;
     51         calc(v,u,ance,dist+1);
     52     }
     53     return;
     54 }
     55 void solve(int x){
     56     vis[x]=1;
     57 //    printf("solve:%d
    ",x);
     58     calc(x,x,x,0);dep[x]--;
     59     for(int i=hd[x];i;i=e[i].nxt){
     60         int v=e[i].v;
     61         if(!vis[v]){
     62             smm=sz[v]; mc[rot=0]=INF;
     63             DFS_sz(v,x);
     64             solve(rot);
     65         }
     66     }
     67     return;
     68 }
     69 void add(int u){
     70     LL tmp=ans1[u];
     71     for(int i=dep[u];i>1;i--){
     72         LL dist=dis[u][i-1];
     73         tmp+=ans1[an[u][i-1]]-ans2[an[u][i]];
     74         tmp+=dist*(num[an[u][i-1]]-num[an[u][i]]);
     75     }
     76     nowans+=tmp;
     77     num[u]+=1;
     78     for(int i=dep[u];i>1;i--){
     79         LL dist=dis[u][i-1];
     80         ans1[an[u][i-1]]+=dist*1;
     81         ans2[an[u][i]]+=dist*1;
     82         num[an[u][i-1]]+=1;
     83     }
     84     return;
     85 }
     86 //
     87 int ch[mxn][2];
     88 //int st[mxn],top=0;
     89 int n,x[mxn],M[mxn],U[mxn];
     90 set<int>st;
     91 void init(){
     92     st.insert(x[1]);set<int>::iterator it,it2;
     93     for(int i=2;i<=n;i++){
     94         st.insert(x[i]);
     95         it=it2=st.lower_bound(x[i]);
     96         if(it!=st.end()){it++;if(it!=st.end())U[i]=(*it);}
     97         if(it2!=st.begin()){it2--; M[i]=(*it2);}
     98     }
     99     for(int i=2;i<=n;i++){
    100         if(!M[i] || ch[M[i]][1]){
    101             ch[U[i]][0]=x[i];
    102             insert(U[i],x[i]);
    103             continue;
    104         }
    105         if(!U[i] || ch[U[i]][0]){
    106             ch[M[i]][1]=x[i];
    107             insert(M[i],x[i]);
    108         }
    109     }
    110     return;
    111 }
    112 int main(){
    113     int i,j;
    114     n=read();
    115     for(i=1;i<=n;i++)x[i]=read();
    116     init();
    117     smm=n;
    118     mc[rot=0]=INF;
    119     DFS_sz(1,0);
    120     solve(rot);
    121     for(i=1;i<=n;i++){
    122         an[i][++dep[i]]=i;
    123         dis[i][dep[i]]=0;
    124     }
    125     for(i=1;i<=n;i++){
    126         add(x[i]);
    127         printf("%lld
    ",nowans);
    128     }
    129     return 0;
    130 }
  • 相关阅读:
    微软教程:ASP.NET Core MVC 入门
    微软教程:ASP.NET Core Razor Pages 入门
    微软教程:ASP.NET Core Web API 入门
    微软教程:ASP.NET Core SignalR 入门(实时Web应用)
    Entity Framework Core 系列教程(翻译)
    视频教程:ASP.NET Core 3.x 构建 RESTful API(高级)
    C#(99):C# 9.0 新特性( NET Framework 5.0 与 Visual Studio ? )
    视频教程:VS Core 40分钟进行WebAPI开发和调用(入门级别)
    视频教程:ASP.NET Core 3.x 入门(包括MVC、Razor Page、Blazor、SignalR、gRPC)
    EntityFramework Core入门教程-12-在ASP.NET Core项目中配置EF Core
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/7095498.html
Copyright © 2011-2022 走看看