zoukankan      html  css  js  c++  java
  • P3521 [POI2011]ROT-Tree Rotations

    P3521 [POI2011]ROT-Tree Rotations

      本题可以通过合并数据结构解决。

      权值线段树合并的时间复杂度为O(nlogn)。

    证明:

       • n个节点相互独立。

       • 考虑合并节点的意义:两棵线段树在当前区间内都有值且新的树在当前区间的值相对原来两棵树的值都增加了。

       • 说明对于一个线段树区间,merge时访问到它的次数不会超过该区间的长度大小次。

       • 那么显然总访问次数的上限为 nlogn。

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 int n,root,now,cnt;
     5 ll a,b,ans;
     6 int sum[4000050];
     7 int son[4000050][2];
     8 void calc_add(int &u,int l,int r)
     9 {
    10     u=++cnt;    ++sum[u];
    11     if(l==r)    return ;
    12     int mid=(l+r)>>1;
    13     if(now<=mid)    calc_add(son[u][0],l,mid);
    14     else            calc_add(son[u][1],mid+1,r);
    15 }
    16 void merge(int &u,int v)
    17 {
    18     if(!u||!v)
    19     {
    20         u=u|v;
    21         return ;
    22     }
    23     sum[u]+=sum[v];
    24     a+=(ll)sum[son[u][0]]*sum[son[v][1]];
    25     b+=(ll)sum[son[u][1]]*sum[son[v][0]];
    26     merge(son[u][0],son[v][0]);
    27     merge(son[u][1],son[v][1]);
    28 }
    29 void dfs(int &u)
    30 {
    31     scanf("%d",&now);
    32     int ls,rs;
    33     if(!now)
    34     {
    35         dfs(ls=0);    dfs(rs=0);
    36         a=b=0;    u=ls;
    37         merge(u,rs);
    38         ans+=min(a,b);
    39     }
    40     else
    41         calc_add(u,1,n);
    42 }
    43 int main()
    44 {
    45     scanf("%d",&n);
    46     dfs(root);
    47     printf("%lld",ans);
    48     return 0;
    49 }
    View Code
  • 相关阅读:
    poj 2560Freckles (krusual)
    ACRush 楼天成回忆录
    大腕版ACMICPC比赛
    POJ刷题
    DataGrid中添加DropdownList时的数据绑定
    【转帖】SQL Server各种日期计算方法(收藏)
    安全配置Win2000服务器
    C#写的一个代码生成器
    .Net 常用加密算法类
    实习之最
  • 原文地址:https://www.cnblogs.com/wyher/p/10371530.html
Copyright © 2011-2022 走看看