模板库
C++:
Dinic
1 namespace NF 2 { 3 const int maxnode=2010,maxedge=30000; 4 typedef int flownum; 5 const flownum inf=1000000000; 6 int last[maxnode],cure[maxnode],dis[maxnode]; 7 struct Edge 8 { 9 int to,next; 10 flownum f; 11 } ed[maxedge]; 12 int totedge=1,S,T,V; 13 void bfs(int x) 14 { 15 dis[x]=0; 16 int l=1,r=1; 17 static int q[maxnode]; 18 q[1]=x; 19 while(l<=r) 20 { 21 int cur=q[l++]; 22 for(int i=last[cur];i;i=ed[i].next) if(ed[i].f>0&&dis[cur]+1<dis[ed[i].to]) 23 { 24 q[++r]=ed[i].to; 25 dis[ed[i].to]=dis[cur]+1; 26 } 27 } 28 for(int i=1;i<=V;++i) cure[i]=last[i]; 29 } 30 flownum dfs(int x,flownum f) 31 { 32 flownum s=0; 33 if(x==T||f==0) return f; 34 for(int i=cure[x];i>0;i=ed[i].next) if(dis[ed[i].to]==dis[x]+1) 35 { 36 flownum t=dfs(ed[i].to,min(f,ed[i].f)); 37 s+=t; 38 f-=t; 39 ed[i].f-=t; 40 ed[i^1].f+=t; 41 cure[x]=i; 42 if(f==0) break; 43 } 44 return s; 45 } 46 flownum dinic() 47 { 48 for(int i=1;i<=V;++i) dis[i]=V+1; 49 bfs(S);return dfs(S,inf); 50 } 51 }
FFT
1 const double pi = acos(-1); 2 struct complexd 3 { 4 double a, b; 5 complexd operator+(const complexd &r) const { 6 return complexd{a + r.a, b + r.b}; 7 } 8 complexd operator-(const complexd &r) const { 9 return complexd{a - r.a, b - r.b}; 10 } 11 complexd operator*(const complexd &r) const { 12 return complexd{a * r.a - b * r.b, a * r.b + b * r.a}; 13 } 14 }; 15 void DFT(int n, complexd a[], complexd w[], int wn) 16 { 17 int j = 0; 18 for(int i = 0; i < n; i++) { 19 if(j > i) std::swap(a[i], a[j]); 20 int k = n >> 1; 21 while(j & k) { 22 j ^= k; 23 k >>= 1; 24 } 25 j ^= k; 26 } 27 int k = 1; 28 for(int m = 1; m < n; m <<= 1) 29 { 30 for(int i = 0; i < n; i += (m << 1)) 31 { 32 for(int j = 0; j < m; ++j) 33 { 34 complexd z1 = a[i + j], z2 = w[(wn >> k) * j] * a[i + m + j]; 35 a[i + m + j] = z1 - z2; 36 a[i + j] = z1 + z2; 37 } 38 } 39 ++k; 40 } 41 } 42 struct Conv { 43 complexd w[MAXN * 4], w_conj[MAXN * 4], ca[MAXN * 4], cb[MAXN * 4]; 44 int wn; 45 Conv(): wn(0) {}; 46 47 void init(int n) { 48 for (int i = 0; i < n; ++i) { 49 w[i].a = cos(2 * pi * i / n); 50 w[i].b = sin(2 * pi * i / n); 51 w_conj[i].a = w[i].a; 52 w_conj[i].b = -w[i].b; 53 } 54 wn = n; 55 } 56 //对长度为n的数组a和长度为m的数组b卷积,下标从0开始,结果放在res数组中 57 void conv(int a[], int b[], int n, int m, int res[]) { 58 int N = 1; 59 while (N < n + m - 1) N <<= 1; 60 if (wn == 0 || wn % N != 0) init(N); 61 for (int i = 0; i < N; ++i) ca[i].a = ca[i].b = cb[i].a = cb[i].b = 0; 62 for (int i = 0; i < n; ++i) ca[i].a = a[i]; 63 for (int i = 0; i < m; ++i) cb[i].a = b[i]; 64 DFT(N, ca, w, wn); 65 DFT(N, cb, w, wn); 66 for (int i = 0; i < N; ++i) ca[i] = ca[i] * cb[i]; 67 DFT(N, ca, w_conj, wn); 68 for (int i = 0; i < n + m - 1; ++i) res[i] = static_cast<int>(ca[i].a / N + 0.5); 69 } 70 void conv(double a[], double b[], int n, int m, double res[]) { 71 int N = 1; 72 while (N < n + m - 1) N <<= 1; 73 if (wn == 0 || wn % N != 0) init(N); 74 for (int i = 0; i < N; ++i) ca[i].a = ca[i].b = cb[i].a = cb[i].b = 0; 75 for (int i = 0; i < n; ++i) ca[i].a = a[i]; 76 for (int i = 0; i < m; ++i) cb[i].a = b[i]; 77 DFT(N, ca, w, wn); 78 DFT(N, cb, w, wn); 79 for (int i = 0; i < N; ++i) ca[i] = ca[i] * cb[i]; 80 DFT(N, ca, w_conj, wn); 81 for (int i = 0; i < n + m - 1; ++i) res[i] = ca[i].a / N; 82 } 83 };
NTT
1 typedef long long ll; 2 const int mod = 998244353, g = 3; 3 ll qp(ll x, int y) { 4 if (y == 0) return 1; 5 ll t = qp(x, y >> 1); 6 t = t * t % mod; 7 if (y & 1) t = t * x % mod; 8 return t; 9 } 10 void DFT(int n, int a[], int w[], int wn) 11 { 12 int j = 0; 13 for(int i = 0; i < n; i++) { 14 if(j > i) std::swap(a[i], a[j]); 15 int k = n >> 1; 16 while(j & k) { 17 j ^= k; 18 k >>= 1; 19 } 20 j ^= k; 21 } 22 int k = 1; 23 for(int m = 1; m < n; m <<= 1) 24 { 25 for(int i = 0; i < n; i += (m << 1)) 26 { 27 for(int j = 0; j < m; ++j) 28 { 29 int z1 = a[i + j], z2 = static_cast<ll>(w[(wn >> k) * j]) * a[i + m + j] % mod; 30 a[i + m + j] = (z1 - z2 + mod) % mod; 31 a[i + j] = (z1 + z2) % mod; 32 } 33 } 34 ++k; 35 } 36 } 37 struct Conv { 38 int w[MAXN * 4], w_conj[MAXN * 4], ca[MAXN * 4], cb[MAXN * 4]; 39 int wn; 40 Conv(): wn(0) {}; 41 42 void init(int n) { 43 assert((mod - 1) % n == 0); 44 ll step = qp(g, (mod - 1) / n); 45 w[0] = w_conj[0] = 1; 46 ll cur = 1; 47 for (int i = 1; i < n; ++i) { 48 cur = cur * step % mod; 49 w_conj[n - i] = w[i] = static_cast<int>(cur); 50 } 51 wn = n; 52 } 53 //对长度为n的数组a和长度为m的数组b卷积,下标从0开始,结果放在res数组中 54 void conv(int a[], int b[], int n, int m, int res[]) { 55 int N = 1; 56 while (N < n + m - 1) N <<= 1; 57 if (wn == 0 || wn % N != 0) init(N); 58 for (int i = 0; i < N; ++i) ca[i] = cb[i] = 0; 59 for (int i = 0; i < n; ++i) ca[i] = a[i]; 60 for (int i = 0; i < m; ++i) cb[i] = b[i]; 61 DFT(N, ca, w, wn); 62 DFT(N, cb, w, wn); 63 for (int i = 0; i < N; ++i) ca[i] = static_cast<ll>(ca[i]) * cb[i] % mod; 64 DFT(N, ca, w_conj, wn); 65 ll N_inv = qp(N, mod - 2); 66 for (int i = 0; i < n + m - 1; ++i) res[i] = ca[i] * N_inv % mod; 67 } 68 };
后缀数组
1 using std::string; 2 int sa[maxn],rk[maxn],tsa[maxn],trk[maxn],cnt[maxn],height[maxn]; 3 void getsa(string s) 4 { 5 6 n=s.length(); 7 for(int i=1;i<=n;i++)rk[i]=s[i-1]; 8 int m=255; 9 for(int i=1;i<=n;i++) ++cnt[rk[i]]; 10 for(int i=1;i<=m;i++) cnt[i]+=cnt[i-1]; 11 for(int i=n;i>0;i--) 12 { 13 sa[cnt[rk[i]]--]=i; 14 } 15 for(int k=1;k<n;k<<=1) 16 { 17 int p=0; 18 for(int i=n-k+1;i<=n;i++) tsa[++p]=i; 19 for(int i=1;i<=n;i++) if(sa[i]>k) 20 { 21 tsa[++p]=sa[i]-k; 22 } 23 for(int i=0;i<=m;i++) cnt[i]=0; 24 for(int i=1;i<=n;i++) ++cnt[rk[i]]; 25 for(int i=1;i<=m;i++) cnt[i]+=cnt[i-1]; 26 for(int i=n;i>0;i--) 27 { 28 sa[cnt[rk[tsa[i]]]--]=tsa[i]; 29 } 30 p=0; 31 for(int i=1;i<=n;i++) 32 { 33 if(i==1||rk[sa[i]]!=rk[sa[i-1]]||(sa[i-1]+k>n||sa[i]+k>n||rk[sa[i]+k]!=rk[sa[i-1]+k])) ++p; 34 trk[sa[i]]=p; 35 } 36 m=p; 37 for(int i=1;i<=n;i++) rk[i]=trk[i]; 38 } 39 int p=0; 40 for(int i=1;i<=n;i++) if(rk[i]>1) 41 { 42 if(p>0)--p; 43 int j=sa[rk[i]-1]; 44 while(i+p<=n&&j+p<=n&&s[i+p-1]==s[j+p-1])++p; 45 height[rk[i]]=p; 46 } 47 }
split-merge实现的treap
1 struct Node 2 { 3 int ls,rs,w;//左孩子,右孩子,treap的堆权 4 ...//在节点中记录的其他信息 5 } tp[maxnode]; 6 int totnode=0; 7 void update(int x)//依据孩子的信息更新节点信息 8 { 9 ... 10 } 11 int merge(int u,int v) 12 { 13 if(u==0||v==0) return u|v; 14 if(tp[u].w<tp[v].w) 15 { 16 tp[u].rs=merge(tp[u].rs,v); 17 update(u); 18 return u; 19 } else 20 { 21 tp[v].ls=merge(u,tp[v].ls); 22 update(v); 23 return v; 24 } 25 } 26 void split(int x,... /*用于判定节点属于左边还是右边的信息*/,int &lr,int &rr)//lr,rr传回这个子树劈开后的左边和右边的根 27 { 28 if(x==0) 29 { 30 lr=rr=0; 31 return; 32 } 33 if(x在右边) 34 { 35 rr=x; 36 split(tp[x].ls,...,lr,tp[x].ls); 37 } else 38 { 39 lr=x; 40 split(tp[x].rs,...,tp[x].rs,rr); 41 } 42 update(x); 43 }
Splay(洛谷P3369)
1 #include <cstdio> 2 #include <cstdlib> 3 const int maxnode=1e5+10; 4 struct Node 5 { 6 int fa,son[2]; 7 int key,cnt,size; 8 } sp[maxnode]; 9 int root=0,totnode=0; 10 int newnode(int key) 11 { 12 sp[++totnode].key=key; 13 sp[totnode].cnt=sp[totnode].size=1; 14 sp[totnode].fa=sp[totnode].son[0]=sp[totnode].son[1]=0; 15 return totnode; 16 } 17 inline void upd(int x) 18 { 19 sp[x].size=sp[sp[x].son[0]].size+sp[sp[x].son[1]].size+sp[x].cnt; 20 } 21 void rotate(int x,int d) 22 { 23 int f=sp[x].fa,s=sp[x].son[d]; 24 sp[x].son[d]=sp[s].son[d^1]; 25 sp[s].son[d^1]=x; 26 sp[sp[x].son[d]].fa=x; 27 sp[x].fa=s; 28 sp[s].fa=f; 29 if(sp[f].son[0]==x) sp[f].son[0]=s; 30 if(sp[f].son[1]==x) sp[f].son[1]=s; 31 if(x==root) root=s; 32 upd(x); 33 } 34 void splay(int x,int r) 35 { 36 while(sp[x].fa!=r) 37 { 38 int f=sp[x].fa,d=sp[f].son[1]==x; 39 if(sp[f].fa==r) 40 { 41 rotate(f,d); 42 break; 43 } 44 int ff=sp[f].fa; 45 if(sp[ff].son[d]==f) 46 { 47 rotate(ff,d); 48 rotate(f,d); 49 } else 50 { 51 rotate(f,d); 52 rotate(ff,d^1); 53 } 54 } 55 upd(x); 56 } 57 void ins(int x) 58 { 59 if(root==0) {root=newnode(x);return;} 60 int i=root; 61 while(sp[i].key!=x&&sp[i].son[x>sp[i].key]!=0) i=sp[i].son[x>sp[i].key]; 62 if(sp[i].key==x) 63 { 64 splay(i,0); 65 ++sp[i].cnt; 66 ++sp[i].size; 67 } else 68 { 69 int t=sp[i].son[x>sp[i].key]=newnode(x); 70 sp[t].fa=i; 71 splay(t,0); 72 } 73 } 74 void remove(int id) 75 { 76 if(sp[id].son[1]==0) 77 { 78 root=sp[id].son[0]; 79 sp[root].fa=0; 80 return; 81 } 82 int i=sp[id].son[1]; 83 while(sp[i].son[0]>0) i=sp[i].son[0]; 84 splay(i,0); 85 sp[i].son[0]=sp[id].son[0]; 86 sp[sp[i].son[0]].fa=i; 87 upd(i); 88 } 89 int find(int k) 90 { 91 int i=root; 92 while(sp[i].key!=k) i=sp[i].son[k>sp[i].key]; 93 return i; 94 } 95 void rem(int x) 96 { 97 int i=find(x); 98 splay(i,0); 99 --sp[i].cnt; 100 --sp[i].size; 101 if(sp[i].cnt==0) remove(i); 102 } 103 int askrank(int x) 104 { 105 int i=find(x); 106 splay(i,0); 107 return sp[sp[i].son[0]].size+1; 108 } 109 int findrank(int r) 110 { 111 int i=root,cur=0; 112 while(r-cur<=sp[sp[i].son[0]].size||r-cur>sp[sp[i].son[0]].size+sp[i].cnt) 113 { 114 if(r-cur<=sp[sp[i].son[0]].size) i=sp[i].son[0]; else 115 { 116 cur+=sp[sp[i].son[0]].size+sp[i].cnt; 117 i=sp[i].son[1]; 118 } 119 } 120 splay(i,0); 121 return i; 122 } 123 int findpre(int x,int k) 124 { 125 if(x==0) return 0; 126 if(sp[x].key>=k) return findpre(sp[x].son[0],k); 127 int res=findpre(sp[x].son[1],k); 128 if(res!=0) return res;else return x; 129 } 130 int findnext(int x,int k) 131 { 132 if(x==0) return 0; 133 if(sp[x].key<=k) return findnext(sp[x].son[1],k); 134 int res=findnext(sp[x].son[0],k); 135 if(res!=0) return res;else return x; 136 } 137 int main() 138 { 139 int n; 140 scanf("%d",&n); 141 for(int i=1;i<=n;i++) 142 { 143 int op,x; 144 scanf("%d%d",&op,&x); 145 if(op==1) ins(x); 146 else if(op==2) rem(x); 147 else if(op==3) printf("%d\n",askrank(x)); 148 else if(op==4) printf("%d\n",sp[findrank(x)].key); 149 else if(op==5||op==6) 150 { 151 int ans; 152 if(op==5)ans=findpre(root,x);else ans=findnext(root,x); 153 printf("%d\n",sp[ans].key); 154 splay(ans,0); 155 } 156 } 157 return 0; 158 }
LCT(洛谷P3690)
1 #include <cstdio> 2 3 const int MAXN = 100000 + 10; 4 5 struct Node { 6 int v, fa, xor_sum, son[2]; 7 bool rev; 8 } sp[MAXN]; 9 bool isroot(int x) { 10 int f = sp[x].fa; 11 return sp[f].son[0] != x && sp[f].son[1] != x; 12 } 13 void update(int x) { 14 sp[x].xor_sum = sp[x].v ^ sp[sp[x].son[0]].xor_sum ^ sp[sp[x].son[1]].xor_sum; 15 } 16 void pushdown(int x) { 17 if (sp[x].rev) { 18 int l = sp[x].son[0], r = sp[x].son[1]; 19 sp[x].rev = false; 20 sp[x].son[0] = r; 21 sp[x].son[1] = l; 22 sp[l].rev = !sp[l].rev; 23 sp[r].rev = !sp[r].rev; 24 } 25 } 26 void rotate(int x, int dir) { 27 int s = sp[x].son[dir], f = sp[x].fa; 28 sp[x].son[dir] = sp[s].son[dir ^ 1]; 29 if (sp[x].son[dir]) sp[sp[x].son[dir]].fa = x; 30 sp[s].son[dir ^ 1] = x; 31 sp[x].fa = s; 32 sp[s].fa = f; 33 if (sp[f].son[0] == x) sp[f].son[0] = s; 34 if (sp[f].son[1] == x) sp[f].son[1] = s; 35 update(x); 36 } 37 void pdfr(int x) { 38 static int stk[MAXN]; 39 int top = 1; 40 stk[1] = x; 41 while (!isroot(x)) { 42 x = sp[x].fa; 43 stk[++top] = x; 44 } 45 while (top) { 46 pushdown(stk[top]); 47 --top; 48 } 49 } 50 void splay(int x) { 51 pdfr(x); 52 while (!isroot(x)) { 53 int f = sp[x].fa, d = sp[f].son[1] == x; 54 if (isroot(f)) { 55 rotate(f, d); 56 break; 57 } 58 int ff = sp[f].fa; 59 if (sp[ff].son[d] == f) { 60 rotate(ff, d); 61 rotate(f, d); 62 } else { 63 rotate(f, d); 64 rotate(ff, d ^ 1); 65 } 66 } 67 update(x); 68 } 69 void access(int x) { 70 int y = 0; 71 while (x) { 72 splay(x); 73 sp[x].son[1] = y; 74 update(x); 75 y = x; 76 x = sp[x].fa; 77 } 78 } 79 void makeroot(int x) { 80 access(x); 81 splay(x); 82 sp[x].rev = !sp[x].rev; 83 } 84 int find_leftmost(int x) { 85 while (true) { 86 pushdown(x); 87 if (sp[x].son[0]) { 88 x = sp[x].son[0]; 89 } else { 90 break; 91 } 92 } 93 splay(x); 94 return x; 95 } 96 void link(int x, int y) { 97 makeroot(x); 98 access(y); 99 splay(y); 100 if (find_leftmost(y) != x) { 101 sp[x].fa = y; 102 } 103 } 104 void cut(int x, int y) { 105 makeroot(x); 106 splay(y); 107 if (sp[y].son[0] == x) { 108 sp[x].fa = 0; 109 sp[y].son[0] = 0; 110 update(y); 111 } else if (sp[y].fa == x) { 112 sp[y].fa = 0; 113 } 114 } 115 int query_xor_sum(int x, int y) { 116 makeroot(x); 117 access(y); 118 splay(y); 119 return sp[y].xor_sum; 120 } 121 122 int main() { 123 int n, m; 124 scanf("%d%d", &n, &m); 125 for (int i = 1; i <= n; ++i) { 126 scanf("%d", &sp[i].v); 127 sp[i].fa = 0; 128 sp[i].xor_sum = sp[i].v; 129 sp[i].son[0] = sp[i].son[1] = 0; 130 sp[i].rev = false; 131 } 132 while (m--) { 133 int op, x, y; 134 scanf("%d%d%d", &op, &x, &y); 135 switch (op) { 136 case 0: 137 printf("%d\n", query_xor_sum(x, y)); 138 break; 139 case 1: 140 link(x, y); 141 break; 142 case 2: 143 cut(x, y); 144 break; 145 case 3: 146 splay(x); 147 sp[x].xor_sum ^= sp[x].v ^ y; 148 sp[x].v = y; 149 break; 150 default: 151 break; 152 } 153 } 154 }
AC自动机
1 //constant:MAXNODE,upper_char,lower_char 2 struct Node 3 { 4 int son[upper_char-lower_char+1]; 5 int fail; 6 //for match counting: 7 int cnt; 8 bool flag; 9 }; 10 struct AC_automaton 11 { 12 Node tr[MAXNODE]; 13 int root,totnode; 14 int q[MAXNODE]; 15 void reset() 16 { 17 totnode=root=1; 18 memset(tr,0,sizeof(tr)); 19 } 20 void trie_ins(char s[]) 21 { 22 int cur=root; 23 for(int i=0;s[i]!=0;++i) 24 { 25 if(tr[cur].son[s[i]-lower_char]==0) tr[cur].son[s[i]-lower_char]=++totnode; 26 cur=tr[cur].son[s[i]-lower_char]; 27 } 28 tr[cur].cnt++; 29 } 30 void build_fail() 31 { 32 tr[root].fail=0; 33 for(char ch=0;ch<=upper_char-lower_char;++ch) tr[0].son[ch]=root; 34 int l=1,r=1; 35 q[1]=root; 36 while(l<=r) 37 { 38 int cur=q[l++]; 39 for(char ch=0;ch<=upper_char-lower_char;++ch) 40 if(tr[cur].son[ch]==0) tr[cur].son[ch]=tr[tr[cur].fail].son[ch];else 41 { 42 tr[tr[cur].son[ch]].fail=tr[tr[cur].fail].son[ch]; 43 q[++r]=tr[cur].son[ch]; 44 } 45 } 46 } 47 int match_count(char s[]) 48 { 49 int ret=0,cur=root; 50 for(int i=0;s[i]!=0;++i) 51 { 52 cur=tr[cur].son[s[i]-lower_char]; 53 for(int j=cur;j!=root&&!tr[j].flag;j=tr[j].fail) 54 { 55 tr[j].flag=true; 56 ret+=tr[j].cnt; 57 } 58 } 59 return ret; 60 } 61 };
快速读入int
1 inline int read() 2 { 3 int x=0,f=1;char ch=getchar(); 4 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 5 while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();} 6 return f<0?-x:x; 7 }
KMP
1 //id start from 1 2 void build_next(int n,int a[],int next[]) 3 { 4 next[1]=0; 5 for(int i=2;i<=n;++i) 6 { 7 int j=next[i-1]; 8 while(j>0&&a[j+1]!=a[i]) j=next[j]; 9 if(a[j+1]==a[i]) ++j; 10 next[i]=j; 11 } 12 } 13 int match(int n,int a[],int m,int b[],int next[])//when failing to match,return -1 14 { 15 int j=0; 16 for(int i=1;i<=n;++i) 17 { 18 while(j>0&&b[j+1]!=a[i]) j=next[j]; 19 if(b[j+1]==a[i]) ++j; 20 if(j==m) return i-m+1; 21 } 22 return -1; 23 }
manacher
1 void manacher(char a[],int n,int p[]) 2 { 3 int curmid=0,maxr=0; 4 for(int i=1;i<=n;++i) 5 { 6 if(i>maxr)p[i]=1; else p[i]=min(p[curmid*2-i],maxr-i+1); 7 while(i+p[i]<=n&&i-p[i]>0&&a[i+p[i]]==a[i-p[i]]) ++p[i]; 8 if(i+p[i]-1>maxr) 9 { 10 maxr=i+p[i]-1; 11 curmid=i; 12 } 13 } 14 }
Pascal:
qsort
procedure sort(l,r:longint); var i,j,mid:longint; begin i:=l;j:=r;mid:=a[(l+r) shr 1]; repeat while a[i]<mid do inc(i); while mid<a[j] do dec(j); if i<=j then begin swap(a[i],a[j]); inc(i);dec(j); end; until i>j; if i<r then sort(i,r); if j>l then sort(l,j); end;
后缀数组(UOJ模板题)
program uoj35; const maxn=100010; type arr=array[0..maxn] of longint; var cnt,x0,y0,sa,rank,height:arr; x,y,t:^arr; s:ansistring; n,m,p,k,i,j:longint; begin readln(s); n:=length(s); m:=128; for i:=1 to n do x0[i]:=ord(s[i]); fillchar(cnt,sizeof(cnt),0); for i:=1 to n do inc(cnt[x0[i]]); for i:=1 to m do cnt[i]:=cnt[i]+cnt[i-1]; for i:=n downto 1 do begin sa[cnt[x0[i]]]:=i; dec(cnt[x0[i]]); end; k:=1; x:=@x0; y:=@y0; while true do begin p:=0; for i:=n-k+1 to n do begin inc(p); y^[p]:=i; end; for i:=1 to n do if sa[i]>k then begin inc(p); y^[p]:=sa[i]-k; end; fillchar(cnt,sizeof(cnt),0); for i:=1 to n do inc(cnt[x^[y^[i]]]); for i:=1 to m do cnt[i]:=cnt[i]+cnt[i-1]; for i:=n downto 1 do begin sa[cnt[x^[y^[i]]]]:=y^[i]; dec(cnt[x^[y^[i]]]); end; t:=x; x:=y; y:=t; p:=0; for i:=1 to n do begin if (y^[sa[i]]<>y^[sa[i-1]])or(y^[sa[i]+k]<>y^[sa[i-1]+k]) then inc(p); x^[sa[i]]:=p; end; if p>=n then break; m:=p; k:=k shl 1; end; for i:=1 to n do write(sa[i],' '); writeln; for i:=1 to n do rank[sa[i]]:=i; p:=0; for i:=1 to n do begin if rank[i]=1 then continue; if p>0 then dec(p); j:=sa[rank[i]-1]; while(i+p<=n)and(j+p<=n)and(s[i+p]=s[j+p]) do inc(p); height[rank[i]]:=p; end; for i:=2 to n do write(height[i],' '); end.
kmp
1 //b[]为模板串 2 next[1]:=0; 3 next[0]:=-1; 4 for i:=2 to m do 5 begin 6 j:=next[i-1]; 7 while(j>0)and(b[j+1]<>b[i]) do j:=next[j]; 8 if b[j+1]=b[i] then next[i]:=j+1 else next[i]:=0; 9 end; 10 i:=1;j:=1; 11 while(i<=n)and(j<=m) do 12 begin 13 if (j=0)or(a[i]=b[j]) then 14 begin 15 inc(i);inc(j); 16 end else j:=next[j-1]+1; 17 end;
FFT(UOJ模板题)
1 program uoj34; 2 uses math; 3 type complex=record a,b:double;end; 4 const maxn=100000+10; 5 var n,l1,l2,k,i:longint; 6 a,b,w:array[0..maxn*4] of complex; 7 procedure add(a,b:complex;var c:complex);inline; 8 begin 9 c.a:=a.a+b.a; 10 c.b:=a.b+b.b; 11 end; 12 procedure times(a,b:complex;var c:complex);inline; 13 begin 14 c.a:=a.a*b.a-a.b*b.b; 15 c.b:=a.a*b.b+a.b*b.a; 16 end; 17 procedure minus(a,b:complex;var c:complex);inline; 18 begin 19 c.a:=a.a-b.a; 20 c.b:=a.b-b.b; 21 end; 22 procedure swap(var x,y:complex); inline; 23 var t:complex; 24 begin 25 t:=x;x:=y;y:=t; 26 end; 27 procedure fft; 28 var i,j,m,k,tmp:longint; 29 z:complex; 30 begin 31 j:=0; 32 for i:=0 to n-1 do 33 begin 34 if i>j then swap(a[i],a[j]); 35 k:=n shr 1; 36 while j and k>0 do 37 begin 38 j:=j xor k; 39 k:=k shr 1; 40 end; 41 j:=j xor k; 42 end; 43 i:=2; 44 while i<=n do 45 begin 46 m:=i shr 1; 47 tmp:=n div i; 48 j:=0; 49 while j<n do 50 begin 51 for k:=0 to m-1 do 52 begin 53 times(a[j+m+k],w[tmp*k],z); 54 minus(a[j+k],z,a[j+m+k]); 55 add(a[j+k],z,a[j+k]); 56 end; 57 j:=j+i; 58 end; 59 i:=i shl 1; 60 end; 61 end; 62 begin 63 readln(l1,l2); 64 inc(l1);inc(l2); 65 n:=max(l1,l2)*2; 66 k:=0; 67 while 1 shl k<n do inc(k); 68 n:=1 shl k; 69 for i:=0 to n-1 do 70 begin 71 w[i].a:=cos(2*pi*i/n); 72 w[i].b:=sin(2*pi*i/n); 73 end; 74 for i:=0 to l1-1 do read(a[i].a); 75 for i:=0 to l2-1 do read(b[i].a); 76 fft; 77 for i:=0 to n-1 do swap(a[i],b[i]); 78 fft; 79 for i:=0 to n-1 do times(a[i],b[i],a[i]); 80 for i:=0 to n-1 do w[i].b:=-w[i].b; 81 fft; 82 for i:=0 to l1+l2-2 do write(round(a[i].a/n),' '); 83 end.
先坑在这儿吧……总是找不到以前比较典型的代码……有时间重写一遍吧