zoukankan      html  css  js  c++  java
  • P2463 [SDOI2008]Sandy的卡片[差分+串拼接后缀数组]

    P2463 [SDOI2008]Sandy的卡片

    套路都差不多,都是差分后二分答案找lcp。只是这题要把多个串拼接起来成为一个大串,中间用某些值域中没有的数字相隔(最好间隔符都不一样想想为什么),排序后在二分答案,开个栈统计即可(保证单次check复杂度O(N))。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int N=120000+7;//m<=101不是m<=100大小没算好坑死我了 
     5 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;}
     6 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;}
     7 inline int read(){
     8     int f=0,x=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
     9     while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();return f?-x:x;
    10 }
    11 int a[N],pos[N],bin[N],vis[N],tot;
    12 int n,l,x,ans,tmp,mid,L,R=100;
    13 
    14 int sa[N],h[N],cnt[N],y[N],rk[N],p,m;
    15 inline void suffix_sort(){m=5002;
    16     for(register int i=1;i<=tot;++i)++cnt[rk[i]=a[i]];
    17     for(register int i=1;i<=m;++i)cnt[i]+=cnt[i-1];
    18     for(register int i=tot;i;--i)sa[cnt[rk[i]]--]=i;
    19     for(register int k=1;k<tot;k<<=1,p=0){
    20         for(register int i=tot-k+1;i<=tot;++i)y[++p]=i;
    21         for(register int i=1;i<=tot;++i)if(sa[i]>k)y[++p]=sa[i]-k;
    22         for(register int i=1;i<=m;++i)cnt[i]=0;
    23         for(register int i=1;i<=tot;++i)++cnt[rk[y[i]]];
    24         for(register int i=1;i<=m;++i)cnt[i]+=cnt[i-1];
    25         for(register int i=tot;i;--i)sa[cnt[rk[y[i]]]--]=y[i];
    26         swap(rk,y);rk[sa[1]]=p=1;
    27         for(register int i=2;i<=tot;++i)rk[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?p:++p;
    28         if(p==tot)break;m=p;
    29     }p=0;
    30     for(register int i=1;i<=tot;h[rk[i]]=p,p?--p:1,++i)while(a[i+p]==a[sa[rk[i]-1]+p]&&++p);
    31 }
    32 
    33 inline int check(int k){
    34     for(register int i=1;a[sa[i]]<=4000;++i){
    35         if(h[i]<k){while(x)vis[bin[x--]]=0;}
    36         if(!vis[pos[sa[i]]])vis[pos[sa[i]]]=1,bin[++x]=pos[sa[i]];
    37         if(x==n)return 1;
    38     }
    39     return 0;
    40 }
    41 
    42 int main(){//freopen("tmp.in","r",stdin);
    43     n=read();
    44     for(register int i=1;i<=n;++i){
    45         l=read();a[++tot]=read();pos[tot]=i;
    46         for(register int j=2;j<=l;++j)a[++tot]=read(),a[tot-1]=a[tot]-a[tot-1]+2000,pos[tot]=i;
    47         a[tot]=i+4000;
    48     }
    49     suffix_sort();
    50     while(L<=R){
    51         mid=L+R>>1;
    52         if(check(mid))ans=mid,L=mid+1;
    53         else R=mid-1;
    54     }
    55     printf("%d
    ",ans+1);
    56     return 0;
    57 }
  • 相关阅读:
    短连接生成
    google 定位 标记 地址解码 逆解码
    Laravel 文件上传
    Laravel
    对接航信开票-在线二维码开票
    win 下 composer 安装
    对接美团外卖开放平台
    IOS 弹框在微信中导致输入框等失焦 偏移问题解决
    微信公众号-高德地图实例
    对接百度地图API 实现地址转经纬度
  • 原文地址:https://www.cnblogs.com/saigyouji-yuyuko/p/10344562.html
Copyright © 2011-2022 走看看