zoukankan      html  css  js  c++  java
  • poj1743 Musical Theme

    神题!!

    2333,要求可以给区间加减同一个数,然后我就懵逼了,,%%题解,可以用差分嘛2333

    所以原来的区间长度差分之后就要减一了,

    然后现在用sa搞出height数组,然后对于>=len(len为二分的答案长度-1)的区间,去里面sa的最大和最小的差,就是这两个子串相距的最远距离了,判断这个是不是满足>len就好

    注意,不能==len,因为这是差分数组,==len的话就相当于重合

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 #define N 100005
     5 #define inf 0x3f3f3f3f
     6 #define LL long long
     7 #define eps 1e-8
     8 using namespace std;
     9 inline int ra()
    10 {
    11     int x=0,f=1; char ch=getchar();
    12     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
    13     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
    14     return x*f;
    15 }
    16 
    17 int sa[2][N],rank[2][N],v[N],height[N];
    18 int p=0,q=1,n;
    19 int a[N];
    20 
    21 void get_height()
    22 {
    23     int k=0;
    24     for (int i=1; i<=n; i++)
    25     {
    26         if (rank[p][i]==1) height[1]=0;
    27         else
    28         {
    29             int j=sa[p][rank[p][i]-1];
    30             while (a[i+k]==a[j+k]) k++;
    31             height[rank[p][i]]=k; k?k--:k;
    32         }
    33     }
    34 }
    35 void cal_sa(int sa[N], int rank[N], int Sa[N], int Rank[N], int k)
    36 {
    37     for (int i=1; i<=n; i++) v[rank[sa[i]]]=i;
    38     for (int i=n; i>=1; i--) if (sa[i]>k) Sa[v[rank[sa[i]-k]]--]=sa[i]-k;
    39     for (int i=n-k+1; i<=n; i++) Sa[v[rank[i]]--]=i;
    40     for (int i=1; i<=n; i++) Rank[Sa[i]]=Rank[Sa[i-1]]+(rank[Sa[i]]!=rank[Sa[i-1]] || rank[Sa[i]+k]!=rank[Sa[i-1]+k]);
    41 }
    42 void work()
    43 {
    44     for (int i=1; i<=n; i++) v[a[i]]++;
    45     for (int i=1; i<=200; i++) v[i]+=v[i-1];
    46     for (int i=1; i<=n; i++) sa[p][v[a[i]]--]=i;
    47     for (int i=1; i<=n; i++) rank[p][sa[p][i]]=rank[p][sa[p][i-1]]+(a[sa[p][i]]!=a[sa[p][i-1]]);
    48     for (int k=1; k<n; k<<=1,swap(p,q)) cal_sa(sa[p],rank[p],sa[q],rank[q],k);
    49     get_height();
    50 }
    51 bool check(int len)
    52 {
    53     int mn=inf,mx=-inf;
    54     for (int i=2; i<=n; i++)
    55     {
    56         if (height[i]>=len)
    57         {
    58             mx=max(mx,max(sa[p][i-1],sa[p][i]));
    59             mn=min(mn,min(sa[p][i-1],sa[p][i]));
    60             if (mx-mn>len) return 1;
    61         }
    62         else mn=inf,mx=-inf;
    63     }
    64     return 0;
    65 }
    66 void solve()
    67 {
    68     int l=0,r=n>>1,ans=0;
    69     while (l<=r)
    70     {
    71         int mid=l+r>>1;
    72         if (check(mid)) ans=mid,l=mid+1; else r=mid-1;
    73     }
    74     printf("%d
    ",ans>=4?ans+1:0);
    75 }
    76 
    77 int main(int argc, char const *argv[])
    78 {
    79     while (n=ra())
    80     {
    81         int last;
    82         memset(v,0,sizeof(v));
    83         for (int i=1; i<=n; i++)
    84         {
    85             int x=ra();
    86             if (i!=1) a[i-1]=x-last+100;
    87             last=x;
    88         }
    89         n--; work();
    90         solve();
    91     }
    92     return 0;
    93 }
  • 相关阅读:
    Vue之利用vueRouter的元信息实现页面的缓存
    Vue之directives所遇小bug
    《CSS世界》读书笔记
    git 错误error: failed to push some refs to
    v-text指令消除刷新慢显示替换的过程
    防抖案例实战之仿百度搜索框即时搜索
    数字金额转大写金额
    常见前端安全
    sendmail邮箱部署设置
    Shell之监控cpu、内存、磁盘脚本
  • 原文地址:https://www.cnblogs.com/ccd2333/p/6642193.html
Copyright © 2011-2022 走看看