zoukankan      html  css  js  c++  java
  • 宇宙旅行

    题意:

    在一个外向基环树森林里求最长上升子序列。

    此处的子序列是指在一条路径上。

    n <= 100000

    解:

    硬是想不出来......

    回忆一般的最长单增子序列做法,我们有个f[]数组表示的是i长度的最小结尾。

    那放到树上怎么搞呢?

    我们可以DFS,然后发现每到一个点,f数组只会变动一位,于是我们可以记录下来,回溯的时候消除影响。

    然后就是一大堆毒瘤的细节处理.....

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <cstring>
      4 
      5 const int N = 100010, INF = 0x7f7f7f7f;
      6 
      7 struct Edge {
      8     int nex, v;
      9 }edge[N << 1]; int top;
     10 
     11 int e[N], val[N], to[N], stk[N], t, f[N], c, gt[N], ans = 1;
     12 bool in_stk[N], vis[N];
     13 
     14 inline void add(int x, int y) {
     15     top++;
     16     edge[top].nex = e[x];
     17     edge[top].v = y;
     18     e[x] = top;
     19     return;
     20 }
     21 
     22 inline void DFS_1(int x) {
     23     if(in_stk[x]) {
     24         c = x;
     25         return;
     26     }
     27     if(vis[x]) {
     28         return;
     29     }
     30     in_stk[x] = 1;
     31     stk[++t] = x;
     32     vis[x] = 1;
     33     DFS_1(gt[x]);
     34     t--;
     35     in_stk[x] = 0;
     36     return;
     37 }
     38 
     39 void DFS(int x) {
     40     int l = 0, r = top;
     41     while(l < r) {
     42         int mid = (l + r + 1) >> 1;
     43         if(f[mid] < val[x]) {
     44             l = mid;
     45         }
     46         else {
     47             r = mid - 1;
     48         }
     49     }
     50     r++;
     51     int t_top = top;
     52     int t_r = f[r];
     53     if(r > top) {
     54         top = r;
     55         f[r] = val[x];
     56     }
     57     ans = std::max(ans, r);
     58     if(val[x] < f[r]) {
     59         f[r] = val[x];
     60     }
     61     for(int i = e[x]; i; i = edge[i].nex) {
     62         int y = edge[i].v;
     63         DFS(y);
     64     }
     65     top = t_top;
     66     f[r] = t_r;
     67     return;
     68 }
     69 
     70 inline void solve() {
     71     int x = c;
     72     top = 0;
     73     do {
     74         f[++top] = val[x];
     75         x = gt[x];
     76     }while(x != c);
     77     std::sort(f + 1, f + top + 1);
     78     top = std::unique(f + 1, f + top + 1) - f - 1;
     79     ans = std::max(ans, top);
     80     x = c;
     81     int y = x;
     82     do {
     83         y = x;
     84         x = gt[x];
     85         for(int i = e[x]; i; i = edge[i].nex) {
     86             int z = edge[i].v;
     87             if(z != y) {
     88                 DFS(z);
     89             }
     90         }
     91     }while(x != c);
     92     memset(f + 1, 0, top * sizeof(int));
     93     return;
     94 }
     95 
     96 int main() {
     97     int n;
     98     val[0] = INF;
     99     scanf("%d", &n);
    100     for(int i = 1; i <= n; i++) {
    101         scanf("%d", &val[i]);
    102     }
    103     for(int i = 1, x; i <= n; i++) {
    104         scanf("%d", &x);
    105         add(x, i);
    106         gt[i] = x;
    107     }
    108 
    109     int tc = -1;
    110     for(int i = 1; i <= n; i++) {
    111         if(!vis[i]) {
    112             DFS_1(i);
    113             if(c != tc) {
    114                 solve();
    115                 tc = c;
    116             }
    117         }
    118     }
    119     printf("%d", ans);
    120     return 0;
    121 }
    AC代码
  • 相关阅读:
    app被Rejected 的各种原因翻译
    UIView Border color
    Centos7下安装docker
    利用Yum彻底移除docker
    Docker删除全部镜像和容器
    【转】哈哈笑一笑
    【转】KAFKA分布式消息系统
    java读取properties文件
    java反序列化php序列化的对象
    Java 1.7.0_06中String类内部实现的一些变化【转】
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/9726480.html
Copyright © 2011-2022 走看看