• UVALive 7148 LRIP


    LRIP
    Time Limit: 10000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu

    解题:树分治

     参考了Oyking大神的解法

    我们用map<int,int>维护上升序列,first表示value,second表示长度,按first由小到大,second由大到小排列,因为在val相同的时候,当然是越长越好,但是,Oyking大神说过的冗余上升序列,意思就是在你的值比他小,长度也比它小,那么在拼接那个下降的序列的时候,就会导致极差大,所以可以删除这些没用的。

    我们在搜索下降序列的时候,可以对map进行lower_bound,找出极差范围内最大的长度,进行合并即可

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 const int maxn = 100010;
      4 struct arc{
      5     int to,next;
      6     arc(int x = 0,int y = -1){
      7         to = x;
      8         next = y;
      9     }
     10 }e[maxn<<1];
     11 bool vis[maxn];
     12 int head[maxn],val[maxn],D,ret,tot;
     13 int sz[maxn],maxson[maxn];
     14 map<int,int>up;
     15 void add(int u,int v){
     16     e[tot] = arc(v,head[u]);
     17     head[u] = tot++;
     18 }
     19 void dfs(int u,int fa){
     20     sz[u] = 1;
     21     maxson[u] = 0;
     22     for(int i = head[u]; ~i; i = e[i].next){
     23         if(e[i].to == fa || vis[e[i].to]) continue;
     24         dfs(e[i].to,u);
     25         sz[u] += sz[e[i].to];
     26         maxson[u] = max(maxson[u],sz[e[i].to]);
     27     }
     28 }
     29 int FindRoot(int sum,int u,int fa){
     30     int ret = u;
     31     maxson[u] = max(maxson[u],sum - sz[u]);
     32     for(int i = head[u]; ~i; i = e[i].next){
     33         if(e[i].to == fa || vis[e[i].to]) continue;
     34         int x = FindRoot(sum,e[i].to,u);
     35         if(maxson[x] < maxson[ret]) ret = x;
     36     }
     37     return ret;
     38 }
     39 void dfs_down(int u,int fa,int len){
     40     auto it = up.lower_bound(val[u] - D);
     41     if(it != up.end()) ret = max(ret,it->second + 1 + len);
     42     for(int i = head[u]; ~i; i = e[i].next){
     43         if(e[i].to == fa || vis[e[i].to] || val[e[i].to] < val[u]) continue;
     44         dfs_down(e[i].to,u,len + 1);
     45     }
     46 }
     47 void insert(int val,int len){
     48     auto x = up.lower_bound(val);
     49     if(x != up.end() && x->second >= len) return;
     50     auto ed = up.upper_bound(val);
     51     auto it = map<int,int>::reverse_iterator(ed);
     52     while(it != up.rend() && it->second <= len) ++it;
     53     up.erase(it.base(),ed);
     54     up[val] = len;
     55 }
     56 void dfs_up(int u,int fa,int len){
     57     insert(val[u],len);
     58     for(int i = head[u]; ~i; i = e[i].next){
     59         if(e[i].to == fa || vis[e[i].to] || val[e[i].to] > val[u]) continue;
     60         dfs_up(e[i].to,u,len + 1);
     61     }
     62 }
     63 void work(int u,vector<int>&son){
     64     up.clear();
     65     up[val[u]] = 0;
     66     for(int v:son){
     67         if(val[v] >= val[u]) dfs_down(v,0,1);
     68         if(val[v] <= val[u]) dfs_up(v,0,1);
     69     }
     70 }
     71 void solve(int u){
     72     dfs(u,0);
     73     int root = FindRoot(sz[u],u,0);
     74     vis[root] = true;
     75     vector<int>son;
     76     for(int i = head[root]; ~i; i = e[i].next)
     77         if(!vis[e[i].to]) son.push_back(e[i].to);
     78     work(root,son);
     79     reverse(son.begin(),son.end());
     80     work(root,son);
     81     for(int i = head[root]; ~i; i = e[i].next)
     82         if(!vis[e[i].to]) solve(e[i].to);
     83 }
     84 int main(){
     85     int kase,n,u,v,cs = 1;
     86     scanf("%d",&kase);
     87     while(kase--){
     88         scanf("%d %d",&n,&D);
     89         memset(head,-1,sizeof head);
     90         memset(vis,false,sizeof vis);
     91         tot = 0;
     92         for(int i = 1; i <= n; ++i)
     93             scanf("%d",val + i);
     94         for(int i = ret = 1; i < n; ++i){
     95             scanf("%d%d",&u,&v);
     96             add(u,v);
     97             add(v,u);
     98         }
     99         solve(1);
    100         printf("Case #%d: %d
    ",cs++,ret);
    101     }
    102     return 0;
    103 }
    View Code
  • 相关阅读:
    第七章读书笔记
    第八章读书笔记
    第五章读书笔记
    第六章读书笔记
    总结
    第四章读书笔记
    第十一章读书笔记
    第十章读书笔记
    第九章读书笔记
    第八章读书笔记
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4908004.html
Copyright © 2020-2023  润新知