模板库

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 }
View Code

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 };
View Code

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 };
View Code

 后缀数组

 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 }
View Code

 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 }
View Code

 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 }
View Code

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 }
View Code

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 };
View Code

 快速读入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 }
View Code

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 }
View Code

 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 }
View Code

 

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;
View Code

后缀数组(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.
View Code

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;
View Code

 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.
View Code

 

先坑在这儿吧……总是找不到以前比较典型的代码……有时间重写一遍吧

posted @ 2017-01-20 22:11  lkmcfj  阅读(279)  评论(0编辑  收藏  举报