zoukankan      html  css  js  c++  java
  • [TS-A1486][2013中国国家集训队第二次作业]树[树的重心,点分治]

    首先考虑暴力,可以枚举每两个点求lca进行计算,复杂度O(n^3logn),再考虑如果枚举每个点作为lca去枚举这个点的子树中的点复杂度会大幅下降,如果我们将每个点递归考虑,每次计算过这个点就把这个点删掉,那么如果每次删掉的点是当前子树的重心,枚举点对的复杂度就只有O(logn),对于每次查询答案在trie树中找到时间复杂度基本可视为O(1),最后在分治同时考虑“关键点”即可。总复杂度O(nlogn)。

      1 #include <iostream>
      2 #include <algorithm>
      3 #include <cstdio>
      4 #include <cstdlib>
      5 #include <cstring>
      6 #include <cmath>
      7 #include <ctime>
      8 
      9 using namespace std;
     10 
     11 struct Edge
     12 {
     13     int    to,next;
     14 }e[210000];
     15 
     16 int    n,k,Ans=-1;
     17 int    Size[110000],cnt,p[110000],f[110000],a[110000];
     18 bool    visited[110000];
     19 
     20 void    Add_edge(const int x,const int y)
     21 {
     22     e[++cnt].to=y;
     23     e[cnt].next=p[x];
     24     p[x]=cnt;
     25     return ;
     26 }
     27 
     28 struct Trie
     29 {
     30     private:
     31         int    c[110000][2];
     32         int    d[3500000];
     33         int    cnt,root;
     34 
     35     public:
     36         void    insert(const int val,const int flag)
     37         {
     38             int    pos=root,temp;
     39             for(int i=30;i>=0;--i)
     40             {
     41                 temp=!!(val&(1<<i));
     42                 if(!c[pos][temp])
     43                 {
     44                     c[pos][temp]=++cnt;
     45                     c[cnt][0]=c[cnt][1]=0;
     46                     d[cnt]=0;
     47                 }
     48                 d[pos]=max(d[pos],flag);
     49                 pos=c[pos][temp];
     50             }
     51             d[pos]=max(d[pos],flag);
     52             return ;
     53         }
     54 
     55         void    query(const int val,const int flag)
     56         {
     57             int    temp,num=0,pos=root;
     58             for(int i=30;i>=0;--i)
     59             {
     60                 temp=!(val&(1<<i));
     61                 if(c[pos][temp] && d[c[pos][temp]]+flag>=k)
     62                 {
     63                     pos=c[pos][temp];
     64                     num|=(1<<i);
     65                 }
     66                 else
     67                 {
     68                     if(!c[pos][temp^1] || d[c[pos][temp^1]]+flag<k)
     69                     {
     70                         num=-1;
     71                         break;
     72                     }
     73                     else    pos=c[pos][temp^1];
     74                 }
     75             }
     76             if(k<=flag)Ans=max(Ans,val);
     77             Ans=max(Ans,num);
     78         }
     79         
     80         void    clear()
     81         {
     82             root=1;
     83             cnt=1;
     84             c[root][0]=c[root][1]=0;
     85             d[root]=0,d[0]=0;
     86             return ;
     87         }
     88 }T;
     89 
     90 int    Dfs(const int S,const int fa)
     91 {
     92     Size[S]=1;
     93     for(int i=p[S];i;i=e[i].next)
     94     {
     95         if(e[i].to!=fa && !visited[e[i].to])
     96             Size[S]+=Dfs(e[i].to,S);
     97     }
     98     return Size[S];
     99 }
    100 
    101 void    Get(const int S,const int fa,int & Centre,int & tot,const int nn)
    102 {
    103     int    Max=0,i;
    104 
    105     for(i=p[S];i;i=e[i].next)
    106     {
    107         if(e[i].to!=fa && !visited[e[i].to])
    108         {
    109             Get(e[i].to,S,Centre,tot,nn);
    110             Max=max(Max,Size[e[i].to]);
    111         }
    112     }
    113     Max=max(Max,nn-Size[S]);
    114     if(tot>Max)tot=Max,Centre=S;
    115     return ;
    116 }
    117 
    118 void    Query(const int S,const int fa,int A,int F)
    119 {
    120     A^=a[S];F+=f[S];
    121     T.query(A,F);
    122     for(int i=p[S];i;i=e[i].next)
    123     {
    124         if(e[i].to!=fa && !visited[e[i].to])
    125             Query(e[i].to,S,A,F);
    126     }
    127     return ;
    128 }
    129 
    130 void    Insert(const int S,const int fa,int A,int F)
    131 {
    132     A^=a[S];F+=f[S];
    133     T.insert(A,F);
    134     for(int i=p[S];i;i=e[i].next)
    135     {
    136         if(e[i].to!=fa && !visited[e[i].to])
    137             Insert(e[i].to,S,A,F);
    138     }
    139     return ;
    140 }
    141 
    142 void    TDC(const int S)
    143 {
    144     int    i,Centre;
    145 
    146     visited[S]=true;
    147     for(i=p[S];i;i=e[i].next)
    148     {
    149         if(!visited[e[i].to])
    150         {
    151             int    tot=n+1;
    152             Dfs(e[i].to,0);
    153             Get(e[i].to,0,Centre,tot,Size[e[i].to]);
    154             TDC(Centre);
    155         }
    156     }
    157     T.clear();
    158     for(i=p[S];i;i=e[i].next)
    159     {
    160         if(!visited[e[i].to])
    161         {
    162             Query(e[i].to,0,a[S],f[S]);
    163             Insert(e[i].to,0,0,0);
    164         }
    165     }
    166     T.query(a[S],f[S]);
    167     visited[S]=false;
    168     return ;
    169 }
    170 
    171 int main()
    172 {
    173     int    i,x,y;
    174 
    175     scanf("%d%d",&n,&k);
    176     for(i=1;i<=n;++i)scanf("%d",&f[i]);
    177     for(i=1;i<=n;++i)scanf("%d",&a[i]);
    178 
    179     for(i=1;i<n;++i)
    180     {
    181         scanf("%d%d",&x,&y);
    182         Add_edge(x,y);
    183         Add_edge(y,x);
    184     }
    185 
    186     TDC(1);
    187 
    188     printf("%d
    ",Ans);
    189 
    190     return 0;
    191 }
  • 相关阅读:
    DHT(Distributed Hash Table) Translator
    Introducing shard translator
    【转】shell脚本中echo显示内容带颜色
    javac 错误: 编码GBK的不可映射字符
    一致性哈希(consistent hashing)
    在bash shell中使用getfattr查看文件扩展属性
    css3在不同型号手机浏览器上的兼容一览表
    META是什么意思?
    JS异步加载的三种方式
    AJAX中的同步加载与异步加载
  • 原文地址:https://www.cnblogs.com/Gster/p/5090513.html
Copyright © 2011-2022 走看看