zoukankan      html  css  js  c++  java
  • (SAM)HDU4270 Dynamic Lover

    数了一下,在HDU上总共提交了52次……基本上清一色的都是TLE,其中绝大多数的原因是memcpy时没有按照给定的范围,而是莫名其妙的只memcpy了一部分orz……

    利用性质:在SAM上沿匹配边不断走就能得到所有子串。

    故对题目中的3中操作可以对应于在SAM上进行相应操作。

    1、直接继续在SAM上添加字符串即可

    2、从根节点开始走最多x(x为给定长度)步,每次向可走的最小处(e.g. a不可走,b可走,就走b)转移。走x步,或者遇到包含当前串的后缀串的结点时结束该过程(某结点是否包含当前串的后缀,只需要在此之前从最后添加字符新得到的结点开始沿着slink边走到根节点并一路标记即可),即得到字典序最小的串。

    3、对于删除操作,采用的策略是对每个结点额外记录一个属性,记录该结点是否被删除过。并且记录添加字符串到SAM过程中,某个位置在SAM中的结点编号。由于SAM中某个结点表示一个后缀区间,在往SAM中做添加操作时拆开的点,其对应字符串的结尾是相同的,故其是否被删除过的状态是相同的,为了减少修改操作,将其指向同一个标记数组中的位置即可(用指针、数组记录下标均可)。被删除的点当作无法转移一样处理即可。每次删除只需将连续L个结点修改状态即可,未被删除的结点必定存在某个endpos,满足对应的字符串不包含任何一个被删除的位置。

      1 #include <cstdio>
      2 #include <iostream>
      3 #include <algorithm>
      4 #include <vector>
      5 #include <set>
      6 #include <list>
      7 #include <map>
      8 #include <string>
      9 #include <cstring>
     10 #include <stack>
     11 #include <queue>
     12 #include <cmath>
     13 #include <ctime>
     14 #include <bitset>
     15 #include <utility>
     16 #include <complex>
     17 #include <assert.h>
     18 #include <limits.h>
     19 #include <iomanip>
     20 //#include <bits/stdc++.h>
     21 using namespace std;
     22 #define rank rankk
     23 #define mp make_pair
     24 #define pb push_back
     25 #define xo(a,b) ((b)&1?(a):0)
     26 #define tm tmp
     27 
     28 //#define LL ll
     29 typedef unsigned long long ull;
     30 typedef pair<int,int> pii;
     31 typedef long long ll;
     32 typedef pair<ll,int> pli;
     33 typedef pair<int,ll>pil;
     34 typedef pair<ll,ll> pll;
     35 //const double INF=1e20;
     36 const int INF=0x3f3f3f3f;
     37 //const int INF= 0x7fffffff;
     38 //const ll INF=0x3f3f3f3f3f3f3f3fll;
     39 const ll INFF=0x3f3f3f3f3f3f3fll;
     40 //const ll INFF=1e14+5;
     41 const int MAX=2e5+5;
     42 //const ll MAXN=2e8;
     43 //const int MAX_N=MAX;
     44 //const ll MOD=1e9+7;
     45 const ll MOD=998244353;
     46 //const long double pi=acos(-1.0);
     47 //const double eps=0.00000001;
     48 int gcd(int a,int b){return b?gcd(b,a%b):a;}
     49 template<typename T>inline T abs(T a) {return a>0?a:-a;}
     50 //#define double long double
     51 template<class T> inline
     52 void read(T& num) {
     53     bool start=false,neg=false;
     54     char c;
     55     num=0;
     56     while((c=getchar())!=EOF) {
     57         if(c=='-') start=neg=true;
     58         else if(c>='0' && c<='9') {
     59             start=true;
     60             num=num*10+c-'0';
     61         } else if(start) break;
     62     }
     63     if(neg) num=-num;
     64 }
     65 inline ll powMM(ll a,ll b,ll M){
     66     ll ret=1;
     67     a%=M;
     68 //    b%=M;
     69     while (b){
     70         if (b&1) ret=ret*a%M;
     71         b>>=1;
     72         a=a*a%M;
     73     }
     74     return ret;
     75 }
     76 //const long double eps=-1.0;
     77 //clock_t t1 = clock();
     78 //fprintf(stderr, "%ld ms
    ", clock() - t1);
     79 void open()
     80 {
     81     freopen("in2.txt","r",stdin);
     82     freopen("out2.txt","w",stdout);
     83 }
     84 
     85 const int MAXL=400005;
     86 const int MAXCH=26;
     87 char s[MAXL],q[MAXL];
     88 const char CH='a';
     89 int tot=0;
     90 int cur_len;
     91 int maxlen[MAXL],trans[MAXL][MAXCH],slink[MAXL],pos[MAXL];
     92 int leftmost[MAXL];
     93 int deled[MAXL];
     94 bool D[MAXL];
     95 int DID;
     96 int bck[MAXL];
     97 
     98 int pe,ID;
     99 inline int new_state(int _maxlen,int *_trans,int _slink)
    100 {
    101     maxlen[tot]=_maxlen;
    102     bck[tot]=0;
    103     if(_trans==NULL)
    104         memset(trans[tot],-1,sizeof(trans[tot]));
    105     else
    106         for(int j=0;j<26;j++)trans[tot][j]=_trans[j];
    107     slink[tot]=_slink;
    108     return tot++;
    109 }
    110 char ch;
    111 inline void add_char()
    112 {
    113     ++cur_len;
    114     int c=ch-CH;
    115     int z=new_state(cur_len,NULL,-1);
    116     leftmost[z]=cur_len;
    117     deled[z]=++DID;
    118     D[DID]=0;
    119     pos[cur_len]=z;
    120     int v=pe;
    121     while(v!=-1&&(trans[v][c]==-1||D[deled[trans[v][c]]]))
    122     {
    123         trans[v][c]=z;
    124         v=slink[v];
    125     }
    126     if(v==-1)
    127         slink[z]=0;
    128     else
    129     {
    130         int x=trans[v][c];
    131         if(maxlen[v]+1==maxlen[x])
    132             slink[z]=x;
    133         else
    134         {
    135             int y=new_state(maxlen[v]+1,trans[x],slink[x]);
    136             leftmost[y]=leftmost[x];
    137             slink[y]=slink[x];
    138             deled[y]=deled[x];
    139             slink[x]=y;
    140             slink[z]=y;
    141             int w=v;
    142             while(w!=-1&&trans[w][c]==x)
    143             {
    144                 trans[w][c]=y;
    145                 w=slink[w];
    146             }
    147         }
    148     }
    149     pe=z;
    150     return;
    151 }
    152 inline void Del(int len)
    153 {
    154     while(len--)
    155         D[deled[pos[cur_len--]]]=1;
    156     pe=pos[cur_len];
    157 }
    158 inline void col()
    159 {
    160     int now=pe;
    161     while(now>0)
    162     {
    163         bck[now]=ID;
    164         now=slink[now];
    165     }
    166 }
    167 int main()
    168 {
    169     while(~scanf("%s",s))
    170     {
    171         DID=tot=pe=ID=0;
    172         cur_len=0;
    173         int L=strlen(s);
    174         pos[0]=0;
    175         pe=new_state(0,NULL,-1);
    176         for(int i=0;i<L;i++)
    177         {
    178             ch=s[i];
    179             add_char();
    180         }
    181         int m,k,n;
    182         read(m);
    183         while(m--)
    184         {
    185             read(k);
    186             if(k==1)
    187             {
    188                 scanf("%s",s);
    189                 int ls=strlen(s);
    190                 for(int i=0;i<ls;i++)
    191                 {
    192                     ch=s[i];
    193                     add_char();
    194                 }
    195             }
    196             else if(k==2)
    197             {
    198                 read(n);
    199                 ++ID;
    200                 col();
    201                 int nowlen,len=n;
    202                 int now=0;
    203                 for(nowlen=0;;++nowlen)
    204                 {
    205                     if(nowlen==len)
    206                     {
    207                         printf("%d
    ",leftmost[now]-len+1 );
    208                         break;
    209                     }
    210                     if(bck[now]==ID)
    211                     {
    212                         printf("%d
    ",cur_len-nowlen+1 );
    213                         break; ;
    214                     }
    215                     for(int i=0;i<26;i++)
    216                     {
    217                         int to=trans[now][i];
    218                         if(to!=-1&&!D[deled[to]]){now=to;break;}
    219                     }
    220                 }
    221             }
    222             else
    223             {
    224                 read(n);
    225                 Del(n);
    226             }
    227         }
    228     }
    229     return 0;
    230 }
    231 /*
    232 bcdacdaa
    233 10
    234 3 1
    235 2 2
    236 */
  • 相关阅读:
    Docker Dockerfile 定制镜像
    Nginx之URL重写(rewrite)配置
    Jenkins可用环境变量列表以及环境变量的使用(Shell/Command/Maven/Ant)
    vue实现element-ui对话框可拖拽功能
    配置了ssh免密登录还是提示权限不足怎么解决
    一篇文章彻底搞懂base64编码原理
    想不到吧
    async_retrying
    aiojobs
    python字典不区分大小写
  • 原文地址:https://www.cnblogs.com/quintessence/p/8886887.html
Copyright © 2011-2022 走看看