tmp
Posted happyzym
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了tmp相关的知识,希望对你有一定的参考价值。
h1
h2
h3
h4
h5
h6
删除线
加粗
Luogu
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn = 200;
char s[maxn],str[maxn];
int sa[maxn], t[maxn], t2[maxn], c[maxn];
int n;
//构造字符串s的后缀数组, 每个字符值必须为0 ~ m-1
void build_sa(int m) {
int *x = t, *y = t2;
//基数排序
for(int i = 0; i < m; i++) c[i] = 0;
for(int i = 0; i < n; i++) c[x[i] = s[i]]++;
for(int i = 1; i < m; i++) c[i] += c[i-1];
for(int i = n-1; i >= 0; i--) sa[--c[x[i]]] = i;
for(int k = 1; k <= n; k <<= 1) {
int p = 0;
//直接利用sa数组排序第二关键字
for(int i = n-k; i < n; i++) y[p++] = i;
for(int i = 0; i < n; i++) if(sa[i] >= k) y[p++] = sa[i] - k;
//基数排序第一关键字
for(int i = 0; i < m; i++) c[i] = 0;
for(int i = 0; i < n; i++) c[x[y[i]]]++;
for(int i = 1; i < m; i++) c[i] += c[i-1];
for(int i = n-1; i>= 0; i--) sa[--c[x[y[i]]]] = y[i];
//根据sa和y数组计算新的x数组
swap(x, y);
p = 1;
x[sa[0]] = 0;
for(int i = 1; i < n; i++)
x[sa[i]] = (y[sa[i-1]] == y[sa[i]] && y[sa[i-1]+k] == y[sa[i]+k] ? p-1 : p++);
if(p >= n) break;
m = p;
}
}
int rank_[maxn]; //rank[i]代表后缀i在sa数组中的下标
int height[maxn]; //height[i] 定义为sa[i-1] 和 sa[i] 的最长公共前缀
//后缀j和k的LCP长度等于RMQ(height, rank[j]+1, rank[k])
void get_height() {
int i, j, k = 0;
for(int i = 0; i < n; i++) rank_[sa[i]] = i;
for(int i = 0; i < n; i++) {
if(!rank_[i]) continue;
int j = sa[rank_[i]-1];
if(k) k--;
while(s[i+k] == s[j+k]) k++;
height[rank_[i]] = k;
}
}
int d[maxn][50];
void rmq_init() {
for(int i = 0; i < n; i++) d[i][0] = height[i];
for(int j = 1; (1<<j) <= n; j++)
for(int i = 0; i + (1<<j) - 1 < n; i++)
d[i][j] = min(d[i][j-1], d[i+(1<<(j-1))][j-1]);
}
int rmq(int l, int r) {
if(l == r) return n-l;
if(rank_[l] > rank_[r]) swap(l, r);
int L = rank_[l]+1;
int R = rank_[r];
int k = 0;
while((1<<(k+1)) <= R-L+1) k++;
return min(d[L][k], d[R-(1<<k)+1][k]);
}
//LCP加速多模式匹配
int m;
int cmp_suffix(char* P, int p, int c,int &k) {
k = 0;
int i;
for(i = 0; P[c+i] == s[sa[p]+c+i]; i++) {
if(P[c+i] == ‘ ‘)
return 0;
k++;
}
if(P[c+i] == ‘ ‘)
return 0;
return P[c+i] - s[sa[p]+c+i];
}
vector<int> A;
void b_search(char*P, int L, int R) {
int k;
if(cmp_suffix(P, L, 0, k) < 0) return ;
if(cmp_suffix(P, R, 0, k) > 0) return ;
int c = 0, rr = 0;
int lst = -1;
k = 0;
while(R >= L) {
int M = L + (R-L)/2;
if(lst != -1) c = rmq(lst, sa[M]);
if(c <= k) {
int res = cmp_suffix(P, M, c, k);
rr = res;
if(!res) {
A.push_back(sa[M]);
b_search(P, L, M-1);
b_search(P, M+1, R);
return;
}
lst = sa[M];
if(res < 0) R = M-1; else L = M+1;
}
else if(rr < 0)R = M-1;
else L = M+1;
}
}
void find(char* P) { //找到全部的匹配位置存入A数组中
A.clear();
m = strlen(P);
int L = 0, R = n-1;
b_search(P, L, R);
sort(A.begin(), A.end());
}
int main()
{
scanf("%s",s); n=strlen(s);
build_sa(128);
get_height();
rmq_init();
while(scanf("%s",str)==1)
{
find(str);
for(int i=0;i<A.size();i++) printf("%d ",A[i]); printf("
");
}
return 0;
}
$ L^A_T_E^X $
以上是关于tmp的主要内容,如果未能解决你的问题,请参考以下文章
关于PHP上传文件时配置 php.ini 中的 upload_tmp_dir