zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    ARC109 题解&总结 ABCDEF
    List、Set、Map的学习
    数据结构和算法-栈
    spring-常见知识点(一)
    spring-AOP实现原理(二)
    spring-AOP实现原理(一)
    MVCC详解
    MVCC能否解决幻读
    ArrayList和LinkedList的区别
    架构设计-秒杀架构设计
  • 原文地址:https://www.cnblogs.com/wulangzhou/p/3439320.html
Copyright © 2011-2022 走看看