1.前置知识

以下数字未特殊说明,取值范围均与$N$​​​取交

以下字符串未特殊说明,下标均从1开始,且均为非空串,复杂度中的$n$​​​指字符串长度

周期和border

对于非空集合$S$,定义$\min S$为$S$​中最小的元素,$\max S$为$S$中最大的元素

对于字符串$s$​​,记其长度为$|s|$​​,$s_{i}$​​表示第$i$​​个字符,$s[l,r]$​​表示区间$[l,r]$​​​构成的子串

周期:$1\le x\le |s|$​​为$s$​​的周期当且仅当$\forall 1\le i\le |s|-x,s_{i}=s_{i+x}$​​

记$per(s)$​​为$s$​​​​​​​​​所有周期构成的集合,当$s$​非空时显然$|s|\in per(s)$,即$per(s)\ne \empty$

border:对于$0\le x<|s|$​​​,$s[1,x]$​​​为$s$​​​​​的border当且仅当$s[1,x]=s(|s|-x,|s|]$​​

关于周期和border,显然有以下性质——

性质1:若$x\in per(s)$​​,则$\forall x\le |s[l,r]|,x\in per(s[l,r])$​​

性质2:若$x\in per(s)$,则$\forall 1\le kx\le |s|,kx\in per(s)$

性质3:$x\in per(s)$​​​当且仅当$s[1,|s|-x]$​​为$s$​​​的border

性质4:若$x\in per(s)$,则$\forall y\mid x$且$y\in per(s[l,r])$(其中$x\le |s[l,r]|$),有$y\in per(s)$​

考虑$1\le i\le |s|-y$​,由于$|s[l,r]|\ge x$​,总存在$l\le j\le r$​使得$i\equiv j(mod\ x)$​

接下来,对$j$分类讨论:

1.若$l\le j\le r-y$,即有$s_{i}=s_{j}=s_{j+y}=s_{i+y}$​

2.若$r-y<j\le r$​,则$j>l+(x-y)$​,即有$s_{i}=s_{j}=s_{j-(x-y)}=s_{i+y}$​

综上,可得$y\in per(s)$,即得证

进一步的,还可以得到以下结论——

结论1:若$x,y\in per(s)$​​​且$x+y\le |s|$,则$\gcd(x,y)\in per(s)$

不妨假设$x<y$​,考虑$1\le i\le |s|-(y-x)$,对$i$​分类讨论:

1.若$1\le i\le x$,则$i+y\le |s|$,即有$s_{i}=s_{i+y}=s_{i+(y-x)}$

2.若$x<i\le |s|-(y-x)$​,即有$s_{i}=s_{i-x}=s_{i+(y-x)}$

综上,可得$y-x\in per(s)$

注意到$\gcd(x,y)=\gcd(x,y-x)$​,由此归纳即得证

推论1:若$x=\min per(s)$,则$\forall y\in per(s)$且$x+y\le |s|$,有$x\mid y$

由于$x+y\le |s|$​,根据结论1即$\gcd(x,y)\in per(s)$​

由$x$​​的最小性有$x\le \gcd(x,y)$​​​,同时$x\ne 0$​​,即$\left(x=\gcd(x,y)\right)\mid y$​​

推论2:$per(s)$​​中不超过$\frac{|s|}{2}$​​的元素构成等差数列

令$S=\{x\mid x\le \frac{|s|}{2}$​且$x\in per(s)\}$​,若$S=\empty$​显然成立,下面考虑$S\ne \empty$​时

令$x=\min S$​​​​​,任取$y\in S$​​​​​(不要求$y\ne x$),根据推论1可得$x\mid y$

另一方面,根据性质2,显然这些$y\in S$​​,也即$S=\{y\mid 1\le y\le \frac{|s|}{2}$​​且$x\mid y\}$​​,显然为等差数列

结论2:若$2|s|\ge |t|$​​​,则$S=\{x\mid 0\le x\le |t|-|s|$​​​且$s=t(x,x+|s|]\}$​​​中的元素构成等差数列

若$|S|\le 2$显然成立,下面考虑$|S|\ge 3$​​​​时

对于$x\in S$和$x<y\le |t|-|s|$,$y\in S$显然等价于$s$是$t(x,y+|s|]$的border,进而又等价于$y-x\in per(t(x,y+|s|])$,显然$y-x\le |s|$,那么又可以推出$y-x\in per(s)$

令$x=\min S$​​​​​和$y=\min \complement_{S}\{x\}$​​​​,即有$y-x,z-y\in per(s)$​​​​,显然$(y-x)+(z-y)\le |s|$​​​​,那么根据结论1可得$d=\gcd(y-x,z-y)\in per(s)$​

注意到$d\le \min(y-x,z-y)\le \frac{z-x}{2}\le \frac{|s|}{2}$,令$p=\min per(s)$,同样有$p\le \frac{|s|}{2}$,那么根据推论1即有$p\mid d\mid (y-x),(z-y)$

同时$p\in per(s),y-x\in per(t(x,y+|s|])$,根据性质4可得$p\in per(t(x,y+|s|])$

由$p\mid (y-x)$​可知$p\le y-x$​,因此$p\in per(t(x,x+p+|s|])$​,即等价于$x+p\in S$​

再根据$y$​​​的最小性,有$x+p\ge y$​,同时$p\le y-x$​,也即有$p=(y-x)\mid (z-x)$​,显然$z=x+kp$​​

另一方面,记$z=\max S$,同理有$p\in per(t(x,z+|s|])$,也即有$\forall x+kp\le z,x+kp\in S$​

综上,即得证

推论2:(在结论2中)若$|S|\ge 3$,则该等差数列公差为$\min per(s)$​

证明参考"结论2"的证明

基本字典子串

考虑倍增求后缀数组的过程,记录其中倍增到$2^{m}$​​​​​​​​​时$s(i,i+2^{m}]$​​​​​​​​在所有$0\le i<|s|$​​​​​​​​中的排名$rk_{m}(i)$​​​​​​​​和排名为$i$​​​​​​​​​的集合$S_{m}(i)=\{j\mid rk_{m}(j)=i\}$​​​​

由此,即得到了基本字典子串的结构,构建时空复杂度均为$o(n\log n)$​

关于基本字典子串的一个应用,即快速比较$s[l_{1},r_{1}]$​​和$s[l_{2},r_{2}]$​​​​:

记$L_{i}=r_{i}-l_{i}+1$​​​,显然只需要比较前$L=\min(L_{1},L_{2})$​​​​个字符​​​

令$m$​​​​​​满足$2^{m}<L\le 2^{m+1}$​​​​​​,比较二元组$(rk_{m}(l-1),rk_{m}(r-2^{m}))$​​​​​​​即可,时间复杂度为$o(1)$​

进一步的,也可以将其拓展到trie树上,具体如下:

对于一棵trie树,定义$s(k,l)$表示从节点$k$向上$l$​步所构成的字符串

类似地,可以将基本字典子串拓展到trie树上,将原来的$s(i,i+2^{m}]$变为$s(i,2^{m})$​​即可

同样可以实现快速比较的功能,但此时还需要能快速找到$k$向上$l$步后的终点(即原来$r-2^{m}$​​的位置),可以用离线+dfs来实现

(论文中提到了"长链剖分+ladder"的做法,可以参考相关资料)

2.题目

题面

记$Bd(s)$​为$s$​非空border长度构成的集合​​,给定字符串$s$​​​​​​​​​​​,$q$​​​​​​​​​​​次询问$l$​​​​​​​​​和$r$​​​​​​​​​,求$\min Bd(s[l,r]),\max Bd(s[l,r])$和$|Bd(s[l,r])|$(特别的,若$Bd(s[l,r])=\empty$​​,输出-1)​​​​

$1\le |s|,q\le 2\times 10^{5}$​​​​​​​,$0\le l\le r<|s|$($s$下标从0开始)​​​​​,字符集为小写字母

题解

不妨先不考虑区间的限制,即对整个串$s$​求上述信息

枚举$0\le m\le \lfloor\log_{2}|s|\rfloor$​​​​​,考虑求出$Bd(s)\cap [k,2k)$​​​​​(其中$k=2^{m}$​​​​​):对于$k\le x<2k$​​​​​,显然$x\in Bd(s)$​​​​​当且仅当$x\ne |s|,s[1,k]=s(|s|-x,|s|-x+k]$​​且$s(x-k,x]=s(|s|-k,|s|]$​​​​​​

关于这两个条件,分别求出合法的$x$​​,然后求交即为$Bd(s)\cap [k,2k)$​​

定义$pos(l_{1},r_{1},l_{2},r_{2})=\{x\mid l_{2}\le x\le r_{2}-L_{1}$​​​​​​​且$s(l_{1},r_{1}]=s(x,x+L_{1}]\}$​​​​​​​(其中$L_{i}=r_{i}-l_{i}$​​​​​​​​​),那么问题即求$pos(0,k,|s|-2k+1,|s|)$​​​​​​​​​​​和$pos(|s|-k,|s|,0,2k-1)$​

特别的,在$m=\lfloor\log_{2}|s|\rfloor$​​​时,需要改为$pos(0,k,1,|s|)$​和$pos(|s|-k,|s|,0,|s|-1)$​(防止$x=|s|$​​)

(需要将第一个集合中的元素用$|s|$减去、第二个集合中的元素加上$k$,得到的才是真正的$x$)

显然$2L_{1}\ge L_{2}$​​​​​​​​​​​​,因此根据结论2,其中的元素构成一个等差数列,而一个等差数列只需要求出其中的最小值、次小值和最大值即可确定(公差为次小值-最小值)

进一步的,考虑基本字典子串,即有$pos(l_{1},r_{1},l_{2},r_{2})=S_{m}(rk_{m}(l_{1}))\cap [l_{2},r_{2}-k]$​​,不难二分(初始对其排序)求出最小值、次小值和最大值,时间复杂度为$o(\log n)$​​

将$pos(l_{1},r_{1},l_{2},r_{2})$​对应的等差数列做转换,得到$x$​对应的等差数列,然后将两个等差数列求交,不难发现即是一个扩展欧几里得,时间复杂度也为$o(\log n)$​

综上,得到了一个时空复杂度分别为$o(n\log^{2}n)$​​和$o(n\log n)$​​​​​的​做法

优化

考虑将时间复杂度优化至$o(n\log n)$​​​​​​​​,显然瓶颈有两个:1.等差数列求交;2.求$pos(l_{1},r_{1},l_{2},r_{2})$

关于前者,对两个等差数列长度分类讨论:

1.存在一个等差数列长度小于3,暴力枚举该等差数列元素并检验即可

2.两个等差数列长度都不小于3,则有以下结论——

结论3:若$|s_{1}|=|t_{1}|\ge |s_{2}|=|t_{2}|$且$s_{1}$在$t_{2}t_{1}$、$t_{1}$在$s_{1}s_{2}$中都出现至少3次,则$\min per(s_{1})=\min per(t_{1})$

记$x=\min per(s_{1}),y=\min per(t_{1})$​,若$x\ne y$​,此时不妨假设$x>y$​​(反之同理)

令$z$​​​​​为$s_{1}$​​​​​在$t_{2}t_{1}$​​​​​中最后一次出现的位置(即$z=\max_{0\le x\le |t_{2}|,s_{1}=(t_{2}t_{1})(x,x+|s_{1}|]}x$​​​​​),考虑取出其中$s_{1}$​和$t_{1}$​的交,即$s=s_{1}(|t_{2}|-x,|s_{1}|]=t_{1}[1]$

注意到$s_{1}$​​在$t_{2}s$​​中已经出现了至少三次,且之前每一次匹配都需要额外$x$​​的长度(推论2),因此在长度上不难得到$|t_{2}s|\ge |s_{1}|+2x\ge |t_{2}|+x+y$​,也即$|s|\ge x+y$​

同时,由于$s$是$s_{1}$和$t_{1}$的子串,根据性质1有$x,y \in per(z)$,再根据结论1即有$\gcd(x,y)\in per(z)$

进一步的,根据性质4不难得到$\gcd(x,y)\in per(s_{1})$​,而显然$x>y\ge \gcd(x,y)$​,与$x$最小矛盾

此时代入结论3,令$s_{1}=s(0,k],t_{1}=s(|s|-k,|s|],s_{2}=(k,2k]$和$t_{2}=s(|s|-2k+1,|s|-k]$,即可以得到$\min per(s_{1})=\min per(t_{1})$,再根据推论2两者为公差,也即公差相同,显然可以$o(1)$​求交

关于后者,考虑将$S_{m}(i)$​分为若干段,即$[0,k),[k,2k),[2k,3k),...,[\lfloor\frac{|s|-1}{k}\rfloor k,|s|)$​,根据结论2其中每一段都构成一个等差数列,每一次查询最多有两段有交,显然容易处理

但实现上,如果暴力存储,即将原来的一个vector拆成了$o(n)$个vector,那么总共即有$o(n^{2}\log n)$个vector(其中会有大量的空vector),无法通过

关于这个问题,可以使用哈希,即构造函数$f(m,i,j)$($(m,i,j)$即为vector的下标),值域为$o(n\log n)$,那么期望单次复杂度即为$o(1)$,空间复杂度降为$o(n\log n)$​

综上,得到了一个时空复杂度均为$o(n\log n)$​​的做法

  1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 200009
4 #define L 20
5 #define mod 3000017
6 #define fi first
7 #define se second
8 struct Edge{
9 int nex,id;
10 pair<int,int>to;
11 }edge[L*N];
12 struct Seq{
13 int a,k,d;
14 int st(){
15 return a;
16 }
17 int ed(){
18 return a+(k-1)*d;
19 }
20 int check(int x){
21 if (!k)return 0;
22 if (k==1)return a==x;
23 return (st()<=x)&&(x<=ed())&&((x-a)%d==0);
24 }
25 }o,f[N*L];
26 vector<int>v[L*N];
27 int V,E,n,m,q,x,y,ans_min,ans_max,ans_sum,head[L][mod],Tot[L][mod],a[N],b[N],tot[N],rk[L][N<<1];
28 char s[N];
29 int Hash(int m,int x,int y){
30 int p=((long long)x*N+y)%mod;
31 for(int i=head[m][p];i!=-1;i=edge[i].nex)
32 if (edge[i].to==make_pair(x,y))return edge[i].id;
33 edge[E].nex=head[m][p];
34 edge[E].id=++V;
35 edge[E].to=make_pair(x,y);
36 head[m][p]=E++;
37 return V;
38 }
39 int get_Hash(int m,int x,int y){
40 int p=((long long)x*N+y)%mod;
41 for(int i=head[m][p];i!=-1;i=edge[i].nex)
42 if (edge[i].to==make_pair(x,y))return edge[i].id;
43 return 0;
44 }
45 Seq add(Seq a,int x){
46 if (!a.k)return Seq{0,0,0};
47 a.a+=x;
48 return a;
49 }
50 Seq inv(Seq a){
51 if (!a.k)return Seq{0,0,0};
52 a.a=-a.ed();
53 return a;
54 }
55 Seq Cap(Seq a,int l,int r){
56 if ((!a.k)||(a.st()>r))return Seq{0,0,0};
57 if (a.k==1){
58 if ((l<=a.a)&&(a.a<=r))return a;
59 return Seq{0,0,0};
60 }
61 int s=(l-a.st()+a.d-1)/a.d,t=(r-a.st())/a.d;
62 s=max(s,0),t=min(t,a.k-1);
63 if (s>t)return Seq{0,0,0};
64 return Seq{a.st()+s*a.d,t-s+1,a.d};
65 }
66 Seq merge(Seq a,Seq b){
67 if (!a.k)return b;
68 if (!b.k)return a;
69 return Seq{a.st(),a.k+b.k,b.st()-a.ed()};
70 }
71 Seq get_same(Seq a,Seq b){
72 if (a.k>b.k)swap(a,b);
73 if (a.k<3){
74 vector<int>v;
75 v.clear();
76 for(int i=0;i<a.k;i++)
77 if (b.check(a.a+i*a.d))v.push_back(a.a+i*a.d);
78 if (!v.size())return Seq{0,0,0};
79 if (v.size()==1)return Seq{v[0],1,0};
80 int d=v[1]-v[0];
81 return Seq{v[0],(v.back()-v[0])/d+1,d};
82 }
83 int s=max(a.st(),b.st()),t=min(a.ed(),b.ed());
84 if (s>t)return Seq{0,0,0};
85 return Seq{s,(t-s)/a.d+1,a.d};
86 }
87 Seq get_pos(int l1,int r1,int l2,int r2){
88 l1+=x,r1+=x,l2+=x,r2+=x;
89 Seq o1=Cap(f[get_Hash(m,rk[m][l1],l2/(1<<m))],l2,r2-(1<<m));
90 Seq o2=Cap(f[get_Hash(m,rk[m][l1],l2/(1<<m)+1)],l2,r2-(1<<m));
91 return add(merge(o1,o2),-x);
92 }
93 int main(){
94 scanf("%s%d",s+1,&q);
95 n=strlen(s+1);
96 memset(head,-1,sizeof(head));
97 for(int i=0;i<n;i++){
98 int p=s[i+1]-'a'+1;
99 rk[0][i]=p,v[Hash(0,p,i)].push_back(i);
100 }
101 int t=26;
102 for(m=0;(1<<m)<n;m++){
103 int k=(1<<m);
104 memset(tot,0,sizeof(tot));
105 for(int j=0;j<n;j++)tot[rk[m][j+k]]++;
106 for(int j=1;j<=t;j++)tot[j]+=tot[j-1];
107 for(int j=n-1;j>=0;j--)a[tot[rk[m][j+k]]--]=j;
108 memset(tot,0,sizeof(tot));
109 for(int j=0;j<n;j++)tot[rk[m][j]]++;
110 for(int j=1;j<=t;j++)tot[j]+=tot[j-1];
111 for(int j=n;j;j--)b[tot[rk[m][a[j]]]--]=a[j];
112 t=0;
113 for(int j=1;j<=n;j++){
114 if ((j==1)||(rk[m][b[j]]!=rk[m][b[j-1]])||(rk[m][b[j]+k]!=rk[m][b[j-1]+k]))t++;
115 rk[m+1][b[j]]=t,v[Hash(m+1,t,b[j]/(k<<1))].push_back(b[j]);
116 }
117 }
118 for(int i=1;i<=V;i++){
119 if (!v[i].size())f[i]=Seq{0,0,0};
120 if (v[i].size()==1)f[i]=Seq{v[i][0],1,0};
121 if (v[i].size()>1){
122 int d=v[i][1]-v[i][0];
123 f[i]=Seq{v[i][0],(v[i].back()-v[i][0])/d+1,d};
124 }
125 }
126 for(int i=1;i<=q;i++){
127 scanf("%d%d",&x,&y);
128 int l=y-x+1;
129 ans_min=n,ans_max=0,ans_sum=0;
130 for(m=0;(1<<m)<l;m++){
131 int k=(1<<m);
132 Seq o1=add(inv(get_pos(0,k,max(l-(k<<1),0)+1,l)),l);
133 Seq o2=add(get_pos(l-k,l,0,min((k<<1),l)-1),k);
134 o=get_same(o1,o2);
135 if (o.k){
136 ans_min=min(ans_min,o.st());
137 ans_max=max(ans_max,o.ed());
138 ans_sum+=o.k;
139 }
140 }
141 if (!ans_sum)printf("-1\n");
142 else printf("%d %d %d\n",ans_min,ans_max,ans_sum);
143 }
144 return 0;
145 }

3.拓展

幂和幂串

幂:定义$s$​的$k$​次幂为$s^{k}=ss...s$​(共$k$​个$s$​)​​​

$k$​​​​​​次幂串:$s$​​​​​​为$k$​​​​​​次幂串当且仅当$k\mid |s|$​​​​​且$s=s[1,\frac{|s|}{k}]^{k}$​​(其中$k\ge 2$​)​​

本原$k$​​​次幂串:记$x=\min per(s)$​​​,若$x<|s|$​​​且$x\mid |s|$​​​,则称$s$​​​为本原$\frac{|s|}{x}$​​​​次幂串

本原串:若$\forall x\in per(s)$,有$x=|s|$或$x\not\mid |s|$,则称$s$为本原串

关于幂和幂串,显然有以下性质——

性质5:$\forall k\ge 1,|s|\in per(s^{k})$​

性质6:若$k\mid |s|$​​,$s$​为$k$​次幂串当且仅当$\frac{|s|}{k}\in per(s)$​

性质7:若$s$​​是$k_{1}$​​次幂串和$k_{2}$​​次幂串,则$s$​​是${\rm lcm}(k_{1},k_{2})$​​次幂串

根据性质5,有$\frac{|s|}{k_{1}}\in per(s[1,\frac{|s|}{k_{1}}]^{k_{1}})=per(s)$​,同理有$\frac{|s|}{k_{2}}\in per(s)$​​​​​​​

由于$k\ge 2$​​​,显然$\frac{|s|}{k_{1}}+\frac{|s|}{k_{2}}\le |s|$​​,根据结论1即有$\gcd(\frac{|s|}{k_{1}},\frac{|s|}{k_{2}})=\frac{|s|}{{\rm lcm}(k_{1},k_{2})}\in per(s)$​​

同时${\rm lcm}(k_{1},k_{2})\mid |s|$​,根据性质6即有$s$​为${\rm lcm}(k_{1},k_{2})$次幂串​

性质8:$\forall k\ge 2$​​,$s$​​为本原串当且仅当$s^{k}$​​为本原$k$​​​次幂串

根据性质5,即$|s|\in per(s^{k})$​

令$x=\min per(s^{k})$​,显然$|s^{k}|=k|s|\ge |s|+x$​,根据结论1即$x=\gcd(x,|s|)\mid |s|$​​,再根据性质2即有$x\in per(s)$​

若$s$为本原串,显然$x=|s|$,那么$s^{k}$为本原$\frac{|s^{k}|}{x}=k$次幂串

若$s^{k}$​​​为本原$k$​​​次幂串,显然$x=|s|$​​​,任取$y\in per(s)\mid |s|$​​,根据$|s|\in per(s^{k})$​​和性质4不难得到$y\in per(s^{k})$​​,进而即有$y=|s|$​​($y\ge x=|s|$​)​​

换言之,若$y\mid |s|$​,必然有$y=|s|$​,也即$s$为本原串

综上,即得证

问题

给定字符串$s$​​和$k$​​,快速找到$s$​​的所有本原$k$​​​次幂子串

$1\le |s|\le 2\times 10^{5}$​​,$2\le k\le |s|$​

关于这个问题,考虑下面这个做法:枚举$0\le m\le \lfloor\log_{2}|s|\rfloor$​,排名$i$​和$S_{m}(i)$​中相邻的两个元素$(x,y)$​,并判定$s(x,x+k(y-x)]$​​是否为$k$​次幂子串(若是则加入答案)

(关于判定$s(i,i+kl]$​是否为$k$​次幂串,比较$s(i,i+(k-1)l]$​和$s(i+l,i+kl]$​即可)

显然总复杂度为$o(n\log n)$​​​​,下面考虑正确性——

结论4:该做法恰可以找到所有本原$k$​​​次幂子串

若$s(i,i+kl]$​​​为本原$k$​​​次幂子串,取$m$​​​满足$2^{m-1}<l\le 2^{m}$​​​​,问题即要证明不存在$i<x<i+l$​​使得其满足$s(i,i+l]=s(x,x+l]$​​(那么显然$i$​​和$i+l$​​在$S_{m}(rk_{m}(i))$​​​中相邻,会被枚举到)

若存在$x$​​​​,显然$l,x-i\in per(s(i,x+l])$​​​​​,根据结论1即$d=\gcd(l,x-i)\in per(s(i,x+l])$​​

同时,有$l\in per(s(i,i+kl])$​​,根据性质4即$d\in per(s(i,i+kl])$​​,显然$\min per(s(i,i+kl])<l$​​,与其为本原$k$​​​​次幂串矛盾

另一方面,若找到$s(i,i+kl]$为$k$次幂子串但不为本原$k$次幂子串,令$d=\min per(s(i,i+l])$,显然有此时有${\rm lcp}(s(i,|s|],s(i+d,|s|])>{\rm lcp}(s(i,|s|],s(i+l,|s|])$​

换言之,对于任意$m$若$s(i,i+2^{m}]=s(i+l,i+l+2^{m}]$,则$s(i,i+2^{m}]=s(i+d,i+d+2^{m}]$​​,因此​不会枚举到$i$和$i+l$相邻,即枚举到的一定是本原$k$次幂子串

[nfls338]基本字典子串的更多相关文章

  1. 【DG】Oracle_Data_Guard官方直译

    [DG]Oracle Data Guard官方直译 1 Oracle Data Guard 介绍   Oracle Data Guard概念和管理10g版本2   Oracle Data Guard ...

  2. DVWA实验之Brute Force(暴力破解)- Low

    DVWA实验之Brute Force-暴力破解- Low     这里开始DVWA的相关实验~   有关DVWA环境搭建的教程请参考: https://www.cnblogs.com/0yst3r-2 ...

  3. Oracle错误览表

    Oracle 错误总结及问题解决 ORA     本文转自:https://www.cnblogs.com/zhangwei595806165/p/4972016.html  作者@承影剑 ORA-0 ...

  4. HDU 2846 Repository(字典树,每个子串建树,*s的使用)

    Repository Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  5. Swift3 - String 字符串、Array 数组、Dictionary 字典的使用

    Swift相关知识,本随笔为 字符串.数组.字典的简单使用,有理解.使用错误的地方望能指正. ///************************************************** ...

  6. 萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)

    前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...

  7. trie字典树详解及应用

    原文链接    http://www.cnblogs.com/freewater/archive/2012/09/11/2680480.html Trie树详解及其应用   一.知识简介        ...

  8. python整理之(字符串、元组、列表、字典)

    一.关于字符串的整理总结 对于字符串的操作常用的有这些: 字符串的操作通过dir()函数可以查看 我们先整理没有下划线的用法,有下划线的暂时不去考虑. 1.capitalize 功能:使字符串的首字母 ...

  9. 2.python基础深入(元组、字符串、列表、字典)

    一,对象与类 对象: python中一切皆为对象,所谓对象:我自己就是一个对象,我玩的电脑就是对象,玩的手机就是对象. 我们通过描述属性(特征)和行为来描述一个对象的. 在python中,一个对象的特 ...

随机推荐

  1. 使用node-gyp编写简单的node原生模块

    通过样例,让我们了解如何编写一个node的原生模块.当然,这篇文章还有一个目的,是为了方便以后编写关于node-gyp的文章,搭建初始环境. 基于node-addon-api 基于node-addon ...

  2. 洛谷4219 BJOI2014大融合(LCT维护子树信息)

    QWQ 这个题目是LCT维护子树信息的经典应用 根据题目信息来看,对于一个这条边的两个端点各自的\(size\)乘起来,不过这个应该算呢? 我们可以考虑在LCT上多维护一个\(xv[i]\)表示\(i ...

  3. res目录下的结构

    目录 res目录下的结构 drawable开头的文件夹 mipmap开头的文件夹 values开头的文件夹 layout文件夹 使用res目录下的资源 res目录下的结构 如果你展开res目录看一下, ...

  4. Android应用开发特色

    目录 Android应用开发特色 四大组件 Activity Service Broadcastreceiver Contentprovider 丰富的系统控件 Sqlite数据库 强大的多媒体 An ...

  5. 更好的 java 重试框架 sisyphus 入门简介

    What is Sisyphus sisyphus 综合了 spring-retry 和 gauva-retrying 的优势,使用起来也非常灵活. 为什么选择这个名字 我觉得重试做的事情和西西弗斯很 ...

  6. Spark分区器浅析

    分区器作用:决定该数据在哪个分区 概览: 仅仅只有pairRDD才可能持有分区器,普通RDD的分区器为None 在分区器为None时RDD分区一般继承至父RDD分区 初始RDD分区数: 由集合创建,R ...

  7. (半课内)信安数基 RSA-OAEP 初探

    在RSA攻击中,存在着"小明文攻击"的方式: 在明文够小时,密文也够小,直接开e次方即可: 在明文有点小时,如果e也较小,可用pow(m,e)=n*k+c穷举k尝试爆破 所以,比如 ...

  8. 【c++ Prime 学习笔记】第14章 重载运算与类型转换

    14.1 基本概念 重载的运算符是特殊的函数:名字由关键字operator后接要定义的算符共同组成,也有返回类型.参数列表.函数体. 重载运算符函数的参数量与该算符作用的运算对象数量一样多 除重载调用 ...

  9. 热身训练2 GCD

    题目描述 简要题意:  n个数字,a1,a2,...,an m次询问(l,r),每次询问需回答 1.gcd(al,al+1,al+2,...,ar);2.gcd(ax,ax+1,ax+2,...,ay ...

  10. Linux过来人帮你理清学习思路

    很多同学接触linux不多,对linux平台的开发更是一无所知. 而现在的趋势越来越表明,作为一个优秀的软件开发人员,或计算机it行业从业人员,="" 掌握linux是一种很重要的 ...