数了一下,在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 */