zoukankan      html  css  js  c++  java
  • [bzoj4516] [Sdoi2016]生成魔咒

      强行上hash。。复杂度两个log。。

      把字符串倒过来。就是每次加一个后缀。。就变成问一个后缀会产生多少个不同子串的板子题了。

      听说是SAM板子题..这辈子学不会SAM系列>_<

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define ll long long
     6 #define ull unsigned long long
     7 using namespace std;
     8 const int maxn=100233,base=1e9+9;
     9 int lc[maxn],rc[maxn],val[maxn],rnd[maxn],tot;
    10 ull pre[maxn],jc[maxn];
    11 int s[maxn],sa[maxn],rk[maxn];
    12 int i,j,k,n,m,AFT,PRE,V,rt;
    13 ll ans;
    14  
    15  
    16 int ra;char rx;
    17 inline int read(){
    18     rx=getchar(),ra=0;
    19     while(rx<'0'||rx>'9')rx=getchar();
    20     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    21 }
    22 inline int getlcp(int a,int b){
    23     if(s[a]!=s[b])return 0;
    24     if(a>b)swap(a,b);
    25     int r=n-b+1;
    26     a--,b--;
    27     if(pre[n]-pre[b]*jc[r]==pre[a+r]-pre[a]*jc[r])return r;
    28     int l=1,mid;
    29     while(l<r)
    30         if(pre[b+(mid=l+r+1>>1)]-pre[b]*jc[mid]==pre[a+mid]-pre[a]*jc[mid])
    31             l=mid;else r=mid-1;
    32     return l;
    33 }
    34 inline bool cmp(int a,int b){
    35     int lcp=getlcp(a,b);
    36     return s[a+lcp]<s[b+lcp];
    37 }
    38 inline void getsa(){
    39     int i;
    40     for(i=jc[0]=1;i<=n;i++)pre[i]=pre[i-1]*base+s[i],jc[i]=jc[i-1]*base,sa[i]=i;
    41     sort(sa+1,sa+1+n,cmp);
    42     for(i=1;i<=n;i++)rk[sa[i]]=i;//,printf("   %d",sa[i]);puts("");
    43 //  for(i=1;i<=n;i++)printf("   %d",rk[i]);puts("");
    44 }
    45  
    46 inline void lturn(int &x){int R=rc[x];rc[x]=lc[R],lc[R]=x,x=R;}
    47 inline void rturn(int &x){int L=lc[x];lc[x]=rc[L],rc[L]=x,x=L;}
    48 inline void insert(int &x){
    49     if(!x){x=++tot,val[x]=V,rnd[x]=rand()+tot;return;}
    50     if(V<val[x]){
    51         insert(lc[x]);
    52         if(rnd[lc[x]]<rnd[x])rturn(x);
    53     }else{
    54         insert(rc[x]);
    55         if(rnd[rc[x]]<rnd[x])lturn(x);
    56     }
    57 }
    58 void getpre(int x){
    59     if(!x)return;
    60     if(val[x]<V)PRE=val[x],getpre(rc[x]);
    61     else getpre(lc[x]);
    62 }
    63 void getaft(int x){
    64     if(!x)return;
    65     if(val[x]>V)AFT=val[x],getaft(lc[x]);
    66     else getaft(rc[x]);
    67 }
    68 int main(){
    69     n=read();
    70     for(i=n;i;i--)s[i]=read();
    71 //      n=1e5;  for(i=n;i;i--)s[i]=1;
    72     getsa();//return 233;
    73     ans=1,V=rk[n],insert(rt);printf("%lld
    ",ans);
    74     for(i=n-1;i;i--){
    75         PRE=AFT=0,V=rk[i],getpre(rt),getaft(rt);
    76 //      printf("i:%d  rk:%d   pre:%d  aft:%d
    ",i,rk[i],PRE,AFT);
    77         if(!PRE||!AFT)ans+=n-i+1-getlcp(i,sa[PRE|AFT]);
    78         else ans+=n-i+1-max(getlcp(i,sa[PRE]),getlcp(i,sa[AFT]));
    79         printf("%lld
    ",ans);
    80         V=rk[i],insert(rt);
    81     }//printf("  %lld
    ",ans);
    82     return 0;
    83 }
    84 
    View Code
  • 相关阅读:
    ubuntu 安装FoxitReader福昕阅读器(转载)
    添加中文字库
    操作系统常用调度算法(转载https://www.cnblogs.com/kxdblog/p/4798401.html)
    2802:小游戏利用bfs来实现
    2802:小游戏
    适合使用并行的一种bfs
    (转载)关于usr/bin/ld: cannot find -lxxx问题总结
    gcc5.4报错对‘std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()’未定义的引用
    centos7如何安装gcc5.4
    将含有makefile文件的源码加入Eclipse工程
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5598186.html
Copyright © 2011-2022 走看看