模板库

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 //一个手写的double型复数
 3 {
 4     double a,b;
 5 };
 6 complexd operator +(complexd &x,complexd &y)
 7 {
 8     return (complexd){x.a+y.a,x.b+y.b};
 9 }
10 complexd operator -(complexd &x,complexd &y)
11 {
12     return (complexd){x.a-y.a,x.b-y.b};
13 }
14 complexd operator *(complexd &x,complexd &y)
15 {
16     return (complexd){x.a*y.a-x.b*y.b,x.a*y.b+x.b*y.a};
17 }
18 void DFT(int n,complexd a[],complexd w[])
19 {
20     int j=0;
21     for(int i=0;i<n;i++)
22     {
23         if(j>i) std::swap(a[i],a[j]);
24         int k=n>>1;
25         while(j&k)
26         {
27             j^=k;
28             k>>=1;
29         }
30         j^=k;
31     }
32     for(int m=1;m<n;m<<=1)
33     {
34         for(int i=0;i<n;i+=(m<<1))
35         {
36             for(int j=0;j<m;++j)
37             {
38                 complexd z=w[(n/(m*2))*j]*a[i+m+j];
39                 a[i+m+j]=a[i+j]-z;
40                 a[i+j]=a[i+j]+z;
41             }
42         }
43     }
44 }
45 void conv(int a[],int b[],int n,int m,int res[])//对长度为n的数组a和长度为m的数组b卷积,下标从0开始,结果放在res数组中
46 {
47     static complexd ca[maxn*4],cb[maxn*4],w[maxn*4];
48     int N=n+m-1,k=1;
49     while(k<N)k<<=1;
50     N=k;
51     for(int i=0;i<N;++i) ca[i].a=ca[i].b=cb[i].a=cb[i].b=0;
52     for(int i=0;i<n;++i) ca[i].a=a[i];
53     for(int i=0;i<m;++i) cb[i].a=b[i];
54     for(int i=0;i<N;++i)
55     {
56         w[i].a=cos(2*pi*i/N);
57         w[i].b=sin(2*pi*i/N);
58     }
59     DFT(N,ca,w);
60     DFT(N,cb,w);
61     for(int i=0;i<N;++i) 
62     {
63         w[i].b=-w[i].b;
64         ca[i]=ca[i]*cb[i];
65     }
66     DFT(N,ca,w);
67     for(int i=0;i<n+m-1;++i) res[i]=floor(ca[i].a/N+0.5);
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

 树状数组

 1 int n;
 2 int b[maxn];
 3 inline int lowbit(int x)
 4 {
 5     return x&-x;
 6 }
 7 void edit(int x,int d)
 8 {
 9     while(x<=n)
10     {
11         b[x]+=d;
12         x+=lowbit(x);
13     }
14 }
15 int ask(int x)
16 {
17     int ret=0;
18     while(x)
19     {
20         ret+=b[x];
21         x-=lowbit(x);
22     }
23     return ret;
24 }
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

 并查集

1 int getf(int x)
2 {
3     return fa[x]==x?x:fa[x]=getf(fa[x]);
4 }
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 阅读(...) 评论(...) 编辑 收藏