zoukankan      html  css  js  c++  java
  • 国庆清北 Day5 T3 holyshit

    一道神题 (holyshit)

    Time Limit:1000ms   Memory Limit:128MB

    题目描述

    LYK有n个数ai。

    它想找两段互不相交的区间。

    要求:不存在一个数在这两段区间中总共的出现次数超过1次。

    LYK想使得取出的两段区间的长度的和尽可能大。

    问这个值最大是多少。

    输入格式(holyshit.in)

        第一行一个数n。

    接下来一行n个数ai。

    输出格式(holyshit.out)

        一个数表示可能的最大值是多少

    输入样例

    10

    3 1 2 1 2 4 5 4 5 6

    输出样例

    6

    样例解释

    取区间[1,3]和[8,10]是最优的。

    数据范围

    对于20%的数据n<=10。

    对于40%的数据n<=50。

    对于60%的数据n<=200。

    对于100%的数据2<=n<=2000,1<=ai<=n。

    g[i][j] 表示 [i,j]取一段子区间,没有元素重复,使得子区间长度最长 n^2
    g[i][j-1] g[i+1][j] [i,j]没有元素重复

    1 for (i=n; i>=1; i--){
    2   for (j=1; j<=n; j++) v[j]=false; FLAG=true; 
    3   for (j=i; j<=n; j++){
    4     if (v[a[j]]) FLAG=false;
    5     v[a[j]]=true;
    6     if (FLAG) g[i][j]=j-i+1; else g[i][j]=max(g[i+1][j],g[i][j-1]);
    7   }
    8 }

    先把所有符合条件的区间全部搞出来,由这些区间取扩展到g更大
    [A,B]是合法的, 则 g[A][B]=B-A+1 g[l][r] l<=A r>=B 都有g[l][r]>=B-A+1 n^2

    先枚举第一段区间的右端点r,当l=1时,求出所有×的位置,并求出第二段区间能取的最大长度。
    随着l往右走,部分×被解锁,更新第二段区间的最大长度(并查集实现),然后更新答案。

    f[i]表示在并查集树上的父亲,i的祖先就表示从i出发向右最近×的位置。

    x这个位置被解锁了,getf(x+1)表示新增的区间右端点在哪里, 更新f呢,f[x]=getf(x+1);

  • 相关阅读:
    java面向对象day01
    找工作——JVM内存管理
    找工作——多线程
    找工作-——网络IO
    找工作--volatile
    找工作——异常处理
    找工作--设计模式
    Sqoop安装
    NIO
    Hadoop源码编译
  • 原文地址:https://www.cnblogs.com/lcan/p/9745128.html
Copyright © 2011-2022 走看看