• SGU 507 Treediff


    这个题目  其实可以暴力  用两个 set 合并; 每次放进去一个元素只要找到这个元素第一个比他大的元素和最后一个比他小的元素;然后更新最优值;

    证明为什么不会超时;  假如最后集合的小的为 S1,大的集合为S2; 这样将 S1合并到S2; 这样S2 》= S1×2;合并 t 次后 大小就成了 S1×(2^t); 但是集合大小只有N 个元素  也就是说  N 》= S1×(2^t ); 但S1等于1时 也就是说一个元素最多合并t 《= log(N) 次;

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<set>
     7 using namespace std;
     8 
     9 struct date{
    10    int v,next;
    11 }edge[51234]; int N,M,total,head[51234];
    12 void add_edge( int u,int v ){
    13     edge[total].v = v;
    14     edge[total].next = head[u];
    15     head[u] = total++;
    16 }
    17 inline int min(int a,int b){return a<b?a:b;}
    18 inline int max(int a,int b){return a>b?a:b;}
    19 set<int>s[51234]; int res[51234]; int tab[51234];
    20 int dfs( int sta )
    21 {
    22     bool fell = false; bool fall = false; int ans = 2147483647;
    23     for( int i = head[sta]; i != -1; i = edge[i].next )
    24     {
    25         int v = edge[i].v;  ans = min( ans,dfs( v ) );   set<int>::iterator it,now;
    26         if( !fell ){ tab[sta] = tab[v]; res[sta] = 2147483647; fell = true; continue; }
    27         int len1 = s[tab[sta]].size(); int len2 = s[tab[v]].size();
    28         if( len1 > len2 ){
    29             for( it = s[tab[v]].begin(); it != s[tab[v]].end(); it++ )
    30             {
    31                  now = s[tab[sta]].lower_bound(*it);
    32                  if( now != s[tab[sta]].end() ){ ans = min( ans,*now-*it ); }
    33                  if( now != s[tab[sta]].begin() ){ now--;ans = min( ans,*it-*now ); }
    34                  if( s[tab[sta]].find(*it) == s[tab[sta]].end() ) s[tab[sta]].insert(*it);
    35             }
    36         }else {
    37             for( it = s[tab[sta]].begin(); it != s[tab[sta]].end(); it++ )
    38             {
    39                  now = s[tab[v]].lower_bound(*it);
    40                  if( now != s[tab[v]].end() ){ ans = min( ans,*now-*it ); }
    41                  if( now != s[tab[v]].begin() ){ ans = min( ans,*it-*(--now) ); }
    42                  if( s[tab[v]].find(*it) == s[tab[v]].end() )s[tab[v]].insert(*it);
    43             }
    44             tab[sta] = tab[v];
    45         }
    46     }
    47     res[sta] = ans; return ans;
    48 }
    49 int main( )
    50 {
    51     while( scanf("%d%d",&N,&M) != EOF )
    52     {
    53         for( int i = 0; i <= N; i++ )s[i].clear();
    54         for( int i = 0; i <= N; i++ )tab[i] = i;
    55           total = 0; int k = N-M+1; memset( head,-1,sizeof(head) );
    56         for( int i = 2; i <= N ;i++ ){
    57             int v; scanf("%d",&v);
    58             add_edge( v,i );
    59         }
    60         for( int i = 1; i <= M; i++ ){
    61             int num; scanf("%d",&num); s[k++].insert(num);
    62         }
    63         dfs( 1 );
    64         printf("%d",res[1]);
    65         for( int i = 2; i <= N-M; i++ )
    66         printf(" %d",res[i]);
    67         puts("");
    68     }
    69     return 0;
    70 }
  • 相关阅读:
    linux上安装mysql
    Linux上安装elasticsearch
    解决pyhton aiohttp ssl:None [[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:777)
    mysql数据库的数据变更事件获取以及相关数据
    [天下小黑盒]打地鼠小助手
    看到当年自己学SQL Server 的笔记
    CodeFirst EF中导航属性的个人理解
    在Win10下如何安装IMSL6.0
    商品中台三期压测
    压测
  • 原文地址:https://www.cnblogs.com/wulangzhou/p/3439320.html
Copyright © 2020-2023  润新知