博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

省选前模板整理

[TOC]

 

假装有目录(以前就是有的)

woc明天就走了怎么这么多没写


之前写的忘得差不多了,再写遍(省选部分模板连同一些比较水的。。)。

就按分类顺序排了。另外还是Markdown好用,但可惜不能代码折叠。光改字体就好麻烦啊。。


计算几何。。

DP

斜率优化

 

四边形不等式优化

 


分治

CDQ分治✔

 三维偏序:http://www.cnblogs.com/SovietPower/p/8574905.html

 1 /*
 2 5904kb    840ms
 3 是对x,y,z都相同的元素去重,不是对z。。sb了。
 4 去重后的贡献是q[p].cnt!
 5 */
 6 #include <cstdio>
 7 #include <cctype>
 8 #include <algorithm>
 9 #define gc() getchar()
10 #define lb(x) (x)&-(x)
11 const int N=1e5+5,MAXN=2e5+5;
12 
13 int n,Ans[N];
14 int read();
15 struct Node
16 {
17     int x,y,z,cnt,ans;
18     void Init(){
19         x=read(),y=read(),z=read(),cnt=1;
20     }
21     bool operator <(const Node &a)const{
22         return x==a.x?(y==a.y?z<a.z:y<a.y):x<a.x;
23     }
24 }q[N],tmp[N];
25 
26 inline int read()
27 {
28     int now=0;register char c=gc();
29     for(;!isdigit(c);c=gc());
30     for(;isdigit(c);now=now*10+c-'0',c=gc());
31     return now;
32 }
33 namespace BIT
34 {
35     int n,val[MAXN];
36     inline void Add(int p,int v){
37         while(p<=n) val[p]+=v,p+=lb(p);
38     }
39     inline int Query(int p){
40         int res=0;
41         while(p) res+=val[p],p-=lb(p);
42         return res;
43     }
44     inline void Clear(int p){
45         while(p<=n)
46             if(val[p]) val[p]=0,p+=lb(p);
47             else break;
48     }
49 }
50 void CDQ(int l,int r)
51 {
52     if(l<r){
53         int m=l+r>>1; CDQ(l,m), CDQ(m+1,r);
54         int p1=l,p2=m+1,t=0;
55         while(p1<=m&&p2<=r)
56         {
57             if(q[p1].y<=q[p2].y) BIT::Add(q[p1].z,q[p1].cnt), tmp[t++]=q[p1++];//只是排y,别去管什么z。。
58             else q[p2].ans+=BIT::Query(q[p2].z), tmp[t++]=q[p2++];
59         }
60         if(p1<=m){
61             for(int i=l; i<p1; ++i) BIT::Clear(q[i].z);
62             while(p1<=m) tmp[t++]=q[p1++];
63         }
64         else if(p2<=r){
65             while(p2<=r) q[p2].ans+=BIT::Query(q[p2].z), tmp[t++]=q[p2++];
66             for(int i=l; i<=m; ++i) BIT::Clear(q[i].z);
67         }
68         for(int i=0; i<t; ++i) q[l+i]=tmp[i];
69     }
70 }
71 
72 int main()
73 {
74     n=read(),BIT::n=read();
75     for(int i=1; i<=n; ++i) q[i].Init();
76     std::sort(q+1,q+1+n);
77     int cnt=1;
78     for(int i=2; i<=n; ++i)
79         if(q[i].z!=q[i-1].z||q[i].y!=q[i-1].y||q[i].x!=q[i-1].x) q[++cnt]=q[i];
80         else ++q[cnt].cnt;
81     CDQ(1,cnt);
82     for(int i=1; i<=cnt; ++i) Ans[q[i].ans+q[i].cnt-1]+=q[i].cnt;
83     for(int i=0; i<n; ++i) printf("%d\n",Ans[i]);
84 
85     return 0;
86 }
CDQ分治 三维偏序

点分治✔

http://www.cnblogs.com/SovietPower/p/8589571.html

 1 #include <cstdio>
 2 #include <cctype>
 3 #include <algorithm>
 4 #define gc() getchar()
 5 const int N=1e4+5,S=1e7+5;
 6 
 7 int n,m,Enum,root,Min,sz[N],H[N],to[N<<1],nxt[N<<1],val[N<<1],D[N],que[N],Q[105],Ans[105];
 8 bool vis[N],exist[S];//bitset随便用会更慢。。
 9 
10 inline int read()
11 {
12     int now=0;register char c=gc();
13     for(;!isdigit(c);c=gc());
14     for(;isdigit(c);now=now*10+c-'0',c=gc());
15     return now;
16 }
17 inline void AddEdge(int u,int v,int w)
18 {
19     to[++Enum]=v, nxt[Enum]=H[u], val[Enum]=w, H[u]=Enum;
20     to[++Enum]=u, nxt[Enum]=H[v], val[Enum]=w, H[v]=Enum;
21 }
22 void Get_root(int x,int f,int tot)
23 {
24     int mx=0; sz[x]=1;
25     for(int v,i=H[x]; i; i=nxt[i])
26         if(!vis[v=to[i]] && v!=f)
27         {
28             Get_root(v,x,tot), sz[x]+=sz[v];
29             if(sz[v]>mx) mx=sz[v];
30         }
31     mx=std::max(mx,tot-sz[x]);
32     if(mx<Min) Min=mx,root=x;
33 }
34 void DFS(int x,int f,int d)
35 {
36     D[++D[0]]=d;
37     for(int i=H[x]; i; i=nxt[i])
38         if(!vis[to[i]] && to[i]!=f) DFS(to[i],x,d+val[i]);
39 }
40 void Calc(int x,int val)
41 {
42     D[0]=0, DFS(x,x,val);
43     for(int i=1; i<=D[0]; ++i)
44         for(int j=1; j<=m; ++j)
45             if(Q[j]>=D[i]) Ans[j]|=exist[Q[j]-D[i]];
46     for(int i=1; i<=D[0]; ++i)
47         exist[D[i]]=1,que[++que[0]]=D[i];
48 }
49 void Solve(int x)
50 {
51     vis[x]=1, que[0]=0, exist[0]=1/*!*/;
52     for(int i=H[x]; i; i=nxt[i])
53         if(!vis[to[i]]) Calc(to[i],val[i]);
54     for(int i=1; i<=que[0]; ++i) exist[que[i]]=0;
55     for(int i=H[x]; i; i=nxt[i])
56         if(!vis[to[i]])
57             Min=N, Get_root(to[i],x,sz[to[i]]), Solve(root);
58 }
59 
60 int main()
61 {
62     n=read(),m=read();
63     for(int u,v,i=1; i<n; ++i) u=read(),v=read(),AddEdge(u,v,read());
64     for(int i=1; i<=m; ++i) Q[i]=read();
65     Min=N, Get_root(1,1,n), Solve(root);
66     for(int i=1; i<=m; ++i) puts(Ans[i]?"AYE":"NAY");
67 
68     return 0;
69 }
点分治

数据结构

线段树、树状数组、Trie树略

分块

 

树分块/块状树

 

Splay✔

http://www.cnblogs.com/SovietPower/p/8435011.html

  1 #include <cstdio>
  2 #include <cctype>
  3 #include <algorithm>
  4 //#define gc() getchar()
  5 #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
  6 #define MAXIN 500000
  7 const int N=2e5+5;
  8 
  9 char IN[MAXIN],*SS=IN,*TT=IN;
 10 inline int read()
 11 {
 12     int now=0,f=1;register char c=gc();
 13     for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
 14     for(;isdigit(c);now=now*10+c-'0',c=gc());
 15     return now*f;
 16 }
 17 namespace Splay
 18 {
 19     #define lson son[x][0]
 20     #define rson son[x][1]
 21 
 22     int root,size,fa[N],son[N][2],sz[N],t[N],cnt[N];
 23     inline void Update(int x){
 24         sz[x]=sz[lson]+sz[rson]+cnt[x];
 25     }
 26     void Rotate(int x,int &k)
 27     {
 28         int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1;
 29         if(k==a) k=x;
 30         else son[b][son[b][1]==a]=x;
 31         fa[a]=x, fa[x]=b, fa[son[x][r]]=a,
 32         son[a][l]=son[x][r], son[x][r]=a;
 33         Update(a);// Update(x);
 34     }
 35     void Splay(int x,int &k)
 36     {
 37         while(x!=k)
 38         {
 39             int a=fa[x],b=fa[a];
 40             if(a!=k) (son[a][1]==x^son[b][1]==a)?Rotate(x,k):Rotate(a,k);
 41             Rotate(x,k);
 42         }
 43         Update(x);
 44     }
 45     void Insert(int v,int k)
 46     {
 47         int f=0;
 48         while(t[k]!=v&&k) f=k,k=son[k][v>t[k]];
 49         if(k) ++cnt[k];
 50         else{
 51             k=++size, sz[k]=cnt[k]=1, t[k]=v, fa[k]=f;
 52             if(f) son[f][v>t[f]]=k;
 53         }
 54         Splay(k,root);
 55     }
 56     void Rank(int v,int k)
 57     {
 58 //        if(!k) return;
 59         while(t[k]!=v && son[k][v>t[k]]) k=son[k][v>t[k]];
 60         Splay(k,root);
 61     }
 62     void Delete(int v,int k)
 63     {
 64         Rank(v,root);
 65         if(cnt[root]>1) --cnt[root],--sz[root];
 66         else if(son[root][0]&&son[root][1])
 67         {
 68             int ls=son[root][0],k=son[root][1];
 69             fa[root=k]=0;
 70             while(son[k][0]) k=son[k][0];
 71             fa[ls]=k, son[k][0]=ls;// sz[k]+=sz[ls];
 72             Splay(k,root);
 73         }
 74         else root=son[root][0]^son[root][1],fa[root]=0;
 75     }
 76     int Get_Rank(int k,int x)
 77     {
 78         while(1)
 79         {
 80             if(sz[lson]<k && sz[lson]+cnt[x]>=k) return x;
 81             if(sz[lson]<k) k-=sz[lson]+cnt[x],x=rson;
 82             else x=lson;
 83         }
 84     }
 85     int Find(int v,int w)
 86     {
 87         Rank(v,root);
 88         if((t[root]>v&&!w)||(t[root]<v&&w)) return root;//!
 89         int x=son[root][w^1];
 90         while(son[x][w]) x=son[x][w];
 91         return x;
 92     }
 93 }
 94 using namespace Splay;
 95 
 96 int main()
 97 {
 98     int n=read(),opt;
 99     while(n--)
100         switch(opt=read())
101         {
102             case 1: Insert(read(),root); break;
103             case 2: Delete(read(),root); break;
104             case 3: Rank(read(),root),printf("%d\n",sz[son[root][0]]+1); break;
105             case 4: printf("%d\n",t[Get_Rank(read(),root)]); break;
106             case 5: printf("%d\n",t[Find(read(),1)]); break;
107             case 6: printf("%d\n",t[Find(read(),0)]); break;
108         }
109     return 0;
110 }
Splay

LCT✔

模板:http://www.cnblogs.com/SovietPower/p/8615938.html 

 1 #include <cstdio>
 2 #include <cctype>
 3 #include <algorithm>
 4 #define gc() getchar()
 5 const int N=3e5+5;
 6 
 7 inline int read()
 8 {
 9     int now=0;register char c=gc();
10     for(;!isdigit(c);c=gc());
11     for(;isdigit(c);now=now*10+c-'0',c=gc());
12     return now;
13 }
14 namespace LCT
15 {
16     #define lson son[x][0]
17     #define rson son[x][1]
18 
19     int fa[N],son[N][2],sum[N],val[N],sk[N];
20     bool rev[N];
21     inline void Update(int x){
22         sum[x]=sum[lson]^sum[rson]^val[x];
23     }
24     inline bool n_root(int x){
25         return son[fa[x]][0]==x||son[fa[x]][1]==x;
26     }
27     inline void Rev(int x){
28         std::swap(lson,rson), rev[x]^=1;
29     }
30     inline void PushDown(int x){
31         if(rev[x]) Rev(lson),Rev(rson),rev[x]=0;
32     }
33     void Rotate(int x)
34     {
35         int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1;
36         if(n_root(a)) son[b][son[b][1]==a]=x;
37         if(son[x][r]) fa[son[x][r]]=a;
38         fa[a]=x, fa[x]=b, son[a][l]=son[x][r], son[x][r]=a;
39         Update(a);
40     }
41     void Splay(int x)
42     {
43         int t=1,a=x; sk[1]=x;
44         while(n_root(a)) sk[++t]=a=fa[a];
45         while(t) PushDown(sk[t--]);
46         while(n_root(x))
47         {
48             if(n_root(a=fa[x])) Rotate(son[a][1]==x^son[fa[a]][1]==a?x:a);
49             Rotate(x);
50         }
51         Update(x);
52     }
53     void Access(int x){
54         for(int pre=0; x; x=fa[pre=x])
55             Splay(x), rson=pre, Update(x);
56     }
57     void Make_root(int x){
58         Access(x), Splay(x), Rev(x);
59     }
60     void Split(int x,int y){
61         Make_root(x), Access(y), Splay(y);
62     }
63     int Find_root(int x)
64     {
65         Access(x), Splay(x);
66         while(lson) x=lson;
67         return x;
68     }
69     void Link(int x,int y)
70     {
71         Make_root(x);
72         if(Find_root(y)!=x) fa[x]=y;
73     }
74     void Cut(int x,int y)
75     {
76         Make_root(x);
77         if(Find_root(y)==x&&fa[x]==y&&!rson)
78             fa[x]=son[y][0]=0, Update(y);
79     }
80 }
81 using namespace LCT;
82 
83 int main()
84 {
85     int n=read(),m=read(),opt,x,y;
86     for(int i=1; i<=n; ++i) val[i]=read();
87     while(m--)
88         switch(opt=read(),x=read(),y=read(),opt)
89         {
90             case 0: Split(x,y),printf("%d\n",sum[y]); break;
91             case 1: Link(x,y); break;
92             case 2: Cut(x,y); break;
93             case 3: Splay(x), val[x]=y; break;
94         }
95     return 0;
96 }
LCT

可是很多东西都不熟啊QAQ:http://www.cnblogs.com/SovietPower/category/1182810.html

fhq Treap✔

http://www.cnblogs.com/SovietPower/p/8431909.html

 1 #include <cstdio>
 2 #include <cctype>
 3 #include <algorithm>
 4 #define gc() getchar()
 5 const int N=1e5+5;
 6 
 7 inline int read()
 8 {
 9     int now=0,f=1;register char c=gc();
10     for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
11     for(;isdigit(c);now=now*10+c-'0',c=gc());
12     return now*f;
13 }
14 namespace fhq_Treap
15 {
16     #define lson son[rt][0]
17     #define rson son[rt][1]
18 
19     int tot,fa[N],son[N][2],sz[N],val[N],fix[N];
20     inline int New_Node(int v){
21         fix[++tot]=rand(), val[tot]=v, sz[tot]=1;
22         return tot;
23     }
24     inline void Update(int rt){
25         sz[rt]=sz[lson]+sz[rson]+1;
26     }
27     void Split(int rt,int v,int &x,int &y)
28     {
29         if(!rt) x=y=0;
30         else{
31             if(val[rt]<=v) x=rt,Split(rson,v,rson,y);//val[rt] not val[x]..
32             else y=rt,Split(lson,v,x,lson);
33             Update(rt);
34         }
35     }
36     int Merge(int x,int y)
37     {
38         if(!x||!y) return x^y;
39         if(fix[x]<fix[y]){
40             son[x][1]=Merge(son[x][1],y), Update(x);
41             return x;
42         }
43         else{
44             son[y][0]=Merge(x,son[y][0]), Update(y);
45             return y;
46         }
47     }
48     int Rank(int k,int rt)
49     {
50         while(1)
51         {
52             if(sz[lson]+1==k) return rt;
53             if(sz[lson]<k) k-=sz[lson]+1,rt=rson;
54             else rt=lson;
55         }
56     }
57     int Find(int rt,int w)
58     {
59         while(son[rt][w]) rt=son[rt][w];
60         return rt;
61     }
62 }
63 using namespace fhq_Treap;
64 
65 int main()
66 {
67     int n=read(),opt,v,x,y,z,root=0;
68     while(n--)
69         switch(opt=read(),v=read(),opt)
70         {
71             case 1: Split(root,v,x,y),x=Merge(x,New_Node(v)),root=Merge(x,y);
72                     break;
73             case 2: Split(root,v,x,z),Split(x,v-1,x,y),y=Merge(son[y][0],son[y][1]),root=Merge(Merge(x,y),z);
74                     break;
75             case 3: Split(root,v-1,x,y),printf("%d\n",sz[x]+1),root=Merge(x,y);
76                     break;
77             case 4: printf("%d\n",val[Rank(v,root)]);
78                     break;
79             case 5: Split(root,v-1,x,y),printf("%d\n",val[Find(x,1)]),root=Merge(x,y);
80                     break;
81             case 6: Split(root,v,x,y),printf("%d\n",val[Find(y,0)]),root=Merge(x,y);
82                     break;
83         }
84     return 0;
85 }
fhq Treap

树链剖分

 

树套树 二维线段树

 

主席树 树上第k大(小)✔

区间第k大略

http://www.cnblogs.com/SovietPower/p/8443615.html

 1 //10^5还是需要18*10^5的空间!
 2 #include <cstdio>
 3 #include <cctype>
 4 #include <algorithm>
 5 #define gc() getchar()
 6 const int N=1e5+5;
 7 
 8 int n,Q,cnt,ref[N],A[N],H[N],Enum,nxt[N<<1],to[N<<1],root[N],top[N],dep[N],sz[N],son[N],fa[N];
 9 
10 inline int read()
11 {
12     int now=0,f=1;register char c=gc();
13     for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
14     for(;isdigit(c);now=now*10+c-'0',c=gc());
15     return now*f;
16 }
17 inline void AddEdge(int u,int v)
18 {
19     to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
20     to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
21 }
22 namespace T//Seg_Tree
23 {
24     #define lson son[x][0]
25     #define rson son[x][1]
26 
27     int tot,sum[N*17],son[N*17][2];
28     void Insert(int x,int &y,int l,int r,int p)
29     {
30         sum[y=++tot]=sum[x]+1;
31         if(l<r){
32             int m=l+r>>1;
33             if(p<=m) son[y][1]=rson,Insert(lson,son[y][0],l,m,p);
34             else son[y][0]=lson,Insert(rson,son[y][1],m+1,r,p);
35         }
36     }
37     int Query(int x,int y,int lca,int falca,int l,int r,int k)
38     {
39         if(l==r) return l;
40         int delta=sum[lson]+sum[son[y][0]]-sum[son[lca][0]]-sum[son[falca][0]];
41         if(delta<k) return Query(rson,son[y][1],son[lca][1],son[falca][1],(l+r>>1)+1,r,k-delta);
42         return Query(lson,son[y][0],son[lca][0],son[falca][0],l,l+r>>1,k);
43     }
44 }
45 
46 int Find(int x)
47 {
48     int l=1,r=cnt,mid;
49     while(l<r)
50         if(ref[mid=l+r>>1]<x) l=mid+1;
51         else r=mid;
52     return l;
53 }
54 void DFS1(int x)
55 {
56     int mx=0; sz[x]=1;
57     T::Insert(root[fa[x]],root[x],1,cnt,A[x]);
58     for(int v,i=H[x]; i; i=nxt[i])
59         if((v=to[i])!=fa[x])
60         {
61             fa[v]=x, dep[v]=dep[x]+1, DFS1(v), sz[x]+=sz[v];
62             if(sz[v]>mx) mx=sz[v],son[x]=v;
63         }
64 }
65 void DFS2(int x,int tp)
66 {
67     top[x]=tp;
68     if(son[x]){
69         DFS2(son[x],tp);
70         for(int i=H[x]; i; i=nxt[i])
71             if(to[i]!=fa[x] && to[i]!=son[x]) DFS2(to[i],to[i]);
72     }
73 }
74 int LCA(int u,int v)
75 {
76     while(top[u]!=top[v])
77     {
78         if(dep[top[u]]<dep[top[v]]) std::swap(u,v);
79         u=fa[top[u]];
80     }
81     return dep[u]>dep[v]?v:u;
82 }
83 
84 int main()
85 {
86     n=read(),Q=read();
87     for(int i=1; i<=n; ++i) ref[i]=A[i]=read();
88     for(int u,v,i=1; i<n; ++i) u=read(),v=read(),AddEdge(u,v);
89     std::sort(ref+1,ref+1+n), cnt=1;
90     for(int i=2; i<=n; ++i) if(ref[i]!=ref[i-1]) ref[++cnt]=ref[i];
91     for(int i=1; i<=n; ++i) A[i]=Find(A[i]);
92     DFS1(1), DFS2(1,1);
93     int res=0,u,v,w,k;
94     while(Q--)
95         u=read()^res,v=read(),k=read(),w=LCA(u,v),
96         printf("%d\n",res=ref[T::Query(root[u],root[v],root[w],root[fa[w]],1,cnt,k)]);
97 
98     return 0;
99 }
主席树 静态树上第k小

可并堆 左偏树✔

http://www.cnblogs.com/SovietPower/p/8435041.html

 1 #include <cstdio>
 2 #include <cctype>
 3 #include <algorithm>
 4 //#define gc() getchar()
 5 #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
 6 #define MAXIN 50000//这个到底需要多大啊QAQ 
 7 const int N=1e5+5,DEL=-1<<30;
 8 
 9 char IN[MAXIN],*SS=IN,*TT=IN;
10 namespace Leftist_Tree
11 {
12     #define lson son[x][0]
13     #define rson son[x][1]
14 
15     int fa[N],son[N][2],dis[N],val[N];
16     int Merge(int x,int y)
17     {
18         if(!x||!y) return x^y;
19         if(val[x]>val[y]||(val[x]==val[y]&&x>y)) std::swap(x,y);
20         rson=Merge(rson,y), fa[rson]=x;
21         if(dis[lson]<dis[rson]) std::swap(lson,rson);
22         dis[x]=dis[rson]+1;
23         return x;
24     }
25     inline int Top(int x){
26         while(fa[x]) x=fa[x];
27         return x;
28     }
29 }
30 using namespace Leftist_Tree;
31 
32 inline int read()
33 {
34     int now=0,f=1;register char c=gc();
35     for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
36     for(;isdigit(c);now=now*10+c-'0',c=gc());
37     return now*f;
38 }
39 
40 int main()
41 {
42     dis[0]=-1;
43     int n=read(),Q=read(),opt,x,y;
44     for(int i=1; i<=n; ++i) val[i]=read();
45     while(Q--)
46     {
47         opt=read(),x=read();
48         if(opt==1)
49         {
50             y=read();
51             if(val[x]==DEL||val[y]==DEL||x==y) continue;
52             if((x=Top(x))!=(y=Top(y))) Merge(x,y);
53         }
54         else if(val[x]==DEL) puts("-1");
55         else
56         {
57             printf("%d\n",val[x=Top(x)]),val[x]=DEL;
58             fa[lson]=fa[rson]=0, Merge(lson,rson);//记得清空fa[]!
59         }
60     }
61     return 0;
62 }
Leftist Tree

数学,数论

CRT

 

扩展CRT

 

Lucas

 

扩展Lucas

 

线性求逆元✔

 这么水的东西https://www.luogu.org/problemnew/show/P3811

 1 #include <cstdio>
 2 const int N=3e6+6;
 3 
 4 int n,p,inv[N];
 5 
 6 int main()
 7 {
 8     scanf("%d%d",&n,&p);
 9     inv[1]=1, puts("1");
10     for(int i=2; i<=n; ++i)
11         printf("%d\n",inv[i]=1ll*(p-p/i)*inv[p%i]%p);
12 
13     return 0;
14 }
线性求逆元

Miller Rabin

 

Pollard Rho

上面这俩。。

 

Catalan数

 

博弈论复习

 

高斯消元

 

莫比乌斯反演✔

 做了。


图论

2-SAT

 

Matrix Tree✔

http://www.cnblogs.com/SovietPower/p/8463968.html

就是那样,只会写模板,不再写了。。

二分图匹配 匈牙利

 

欧拉路

 

哈密顿路

 

次小生成树

这个不写了。。倍增十分麻烦,到时候写LCT水过去吧。。

堆优化Dijkstra✔

我。。还是再写遍这个吧

https://www.luogu.org/problemnew/show/P3371

 1 //memset(0x7f)后的值并不是0x7fffffff(略小)!woc才知道。
 2 #include <queue>
 3 #include <cstdio>
 4 #include <cctype>
 5 #include <cstring>
 6 #include <algorithm>
 7 #define gc() getchar()
 8 #define pr std::pair<int,int>
 9 #define mp std::make_pair
10 const int N=1e4+5,M=5e5+5,INF=0x3f3f3f3f;
11 
12 int n,m,S,Enum,H[N],nxt[M],to[M],val[M],dis[N];
13 std::priority_queue<pr> q;
14 bool vis[N];
15 
16 inline int read()
17 {
18     int now=0;register char c=gc();
19     for(;!isdigit(c);c=gc());
20     for(;isdigit(c);now=now*10+c-'0',c=gc());
21     return now;
22 }
23 inline void AddEdge(int u,int v,int w){
24     to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum, val[Enum]=w;
25 }
26 void Dijkstra()
27 {
28     memset(dis,0x3f,sizeof dis);
29     dis[S]=0, q.push(mp(0,S));
30     while(!q.empty())
31     {
32         int x=q.top().second;q.pop();
33         if(vis[x]) continue;
34         vis[x]=1;
35         for(int v,i=H[x]; i; i=nxt[i])
36             if(dis[v=to[i]]>dis[x]+val[i])
37             {
38                 dis[v]=dis[x]+val[i];
39                 if(!vis[v]) q.push(mp(-dis[v],v));
40             }
41     }
42 }
43 
44 int main()
45 {
46     n=read(),m=read(),S=read();
47     for(int u,v,i=1; i<=m; ++i) u=read(),v=read(),AddEdge(u,v,read());
48     Dijkstra();
49     for(int i=1; i<=n; ++i) printf("%d ",dis[i]==INF?0x7fffffff:dis[i]);
50     return 0;
51 }
Dijkstra+heap

网络流

Dinic、ISAP、SPFA费用流略。

无源汇上下界网络流

 

有源汇上下界网络流

 

有源汇上下界最小流

 


字符串

KMP✔

https://www.luogu.org/problemnew/show/P3375

 1 #include <cstdio>
 2 #include <cstring>
 3 const int N=1e6+5;
 4 
 5 int len,fail[N];
 6 char p[N],s[N];
 7 
 8 void Get_fail()
 9 {
10     fail[0]=fail[1]=0;
11     for(int i=1,j; i<len; ++i)
12     {
13         j=fail[i];
14         while(s[i]!=s[j]&&j) j=fail[j];
15         fail[i+1]=s[i]==s[j]?j+1:0;
16     }
17 }
18 void KMP()
19 {
20     for(int i=0,j=0,l=strlen(p); i<l; ++i)
21     {
22         while(p[i]!=s[j]&&j) j=fail[j];
23         if(p[i]==s[j]) ++j;
24         if(j==len) printf("%d\n",i-j+2);
25     }
26     for(int i=1; i<=len; ++i) printf("%d ",fail[i]);
27 }
28 
29 int main()
30 {
31     scanf("%s%s",p,s), len=strlen(s), Get_fail(), KMP();
32     return 0;
33 }
KMP

Manacher✔

http://www.cnblogs.com/SovietPower/p/8677979.html

 1 /*
 2 记录当前ex[]最大的回文中心id和最远延伸范围mx!
 3 关于串的构造: 
 4 应该是 @ #A#B#C#B#A# $,而不是 @ A#B#C#B#A $ 
 5 比如 @a#b#b#c$,答案应是max{ex[i]}-1,而第二种很多情况下答案是max{ex[i]}.
 6 最优解不改串分奇偶讨论感觉sxbk。。
 7 */
 8 #include <cstdio>
 9 #include <cstring>
10 #include <algorithm>
11 const int N=22000010;
12 
13 int n,ex[N];
14 char tmp[N>>1],s[N];
15 
16 void Init()
17 {
18     n=strlen(tmp), s[0]='@';
19     for(int i=0; i<n; ++i)
20         s[i<<1|1]='#', s[(i<<1)+2]=tmp[i];
21     s[n=2*n+2]='$', s[n-1]='#';
22 }
23 void Manacher()
24 {
25     int res=0,mx=0,id;
26     for(int i=1; i<n; ++i)
27     {
28         if(i<mx) ex[i]=std::min(ex[id*2-i],mx-i);
29         else ex[i]=1;
30         while(s[i+ex[i]]==s[i-ex[i]]) ++ex[i];
31 //        if(ex[i]>res) res=ex[i];//不在这更新也对,懒得想了。。
32         if(i+ex[i]>mx) id=i,mx=i+ex[i],res=std::max(res,ex[i]);
33     }
34     printf("%d",res-1);
35 }
36 
37 int main()
38 {
39     scanf("%s",tmp), Init(), Manacher();
40     return 0;
41 }
Manacher

后缀数组✔

http://www.cnblogs.com/SovietPower/p/8567563.html

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 const int N=1e6+5;
 5 
 6 int n,tm[N],sa[N],rk[N],sa2[N],ht[N];
 7 char s[N];
 8 
 9 void Get_SA()
10 {
11     int *x=rk,*y=sa2,m=28;
12     for(int i=0; i<=m; ++i) tm[i]=0;
13     for(int i=1; i<=n; ++i) ++tm[x[i]=s[i]-'a'+1];
14     for(int i=1; i<=m; ++i) tm[i]+=tm[i-1];
15     for(int i=n; i; --i) sa[tm[x[i]]--]=i;
16     for(int k=1,p=0; k<n; k<<=1,m=p,p=0)
17     {
18         for(int i=n-k+1; i<=n; ++i) y[++p]=i;
19         for(int i=1; i<=n; ++i) if(sa[i]>k) y[++p]=sa[i]-k;
20 
21         for(int i=0; i<=m; ++i) tm[i]=0;
22         for(int i=1; i<=n; ++i) ++tm[x[i]];
23         for(int i=1; i<=m; ++i) tm[i]+=tm[i-1];
24         for(int i=n; i; --i) sa[tm[x[y[i]]]--]=y[i];
25 
26         std::swap(x,y), p=x[sa[1]]=1;
27         for(int i=2; i<=n; ++i)
28             x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?p:++p;
29         if(p>=n) break;
30     }
31     for(int i=1; i<=n; ++i) rk[sa[i]]=i;
32     ht[1]=0;
33     for(int k=0,p,i=1; i<=n; ++i)
34     {
35         if(rk[i]==1) continue;
36         if(k) --k;
37         p=sa[rk[i]-1];//ht[i]>=ht[i-1]-1
38         while(i+k<=n&&p+k<=n&&s[i+k]==s[p+k]) ++k;
39         ht[rk[i]]=k;
40     }
41 }
42 
43 int main()
44 {
45     scanf("%s",s+1), n=strlen(s+1), Get_SA();
46     for(int i=1; i<=n; ++i) printf("%d ",sa[i]);putchar('\n');
47     for(int i=2; i<=n; ++i) printf("%d ",ht[i]);
48 
49     return 0;
50 }
后缀数组 倍增

AC自动机✔

http://www.cnblogs.com/SovietPower/p/8530327.html

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 const int N=1e6+5;
 5 
 6 char s[N];
 7 struct AC_Automaton
 8 {
 9     int tot,fail[N],son[N][26],las[N],val[N],q[N];
10     void Insert(char *s)
11     {
12         int l=strlen(s),x=0;
13         for(int id,i=0; i<l; ++i)
14         {
15             id=s[i]-'a';
16             if(!son[x][id]) son[x][id]=++tot;
17             x=son[x][id];
18         }
19         ++val[x];
20     }
21     void Build()
22     {
23         int h=0,t=0;
24         for(int i=0; i<26; ++i)
25             if(son[0][i]) fail[son[0][i]]=0,q[t++]=son[0][i];
26         while(h<t)
27         {
28             int x=q[h++];
29             for(int v,i=0; i<26; ++i)
30                 if(son[x][i])
31                     fail[v=son[x][i]]=son[fail[x]][i],q[t++]=v,las[v]=val[fail[v]]?fail[v]:las[fail[v]];
32                 else son[x][i]=son[fail[x]][i];//直接设son[]。
33         }
34     }
35     void Query(char *s)
36     {
37         int l=strlen(s),res=0,x=0;
38         for(int i=0; i<l; ++i)
39         {
40             x=son[x][s[i]-'a'];//先走一步 
41             for(int j=x; j&&~val[j]; j=las[j])
42                 res+=val[j], val[j]=-1;//不能重复走。
43         }
44         printf("%d",res);
45     }
46 }ac;
47 
48 int main()
49 {
50     int n; scanf("%d",&n);
51     while(n--) scanf("%s",s),ac.Insert(s);
52     ac.Build(), scanf("%s",s), ac.Query(s);
53 
54     return 0;
55 }
AC Automaton
 1 #include <cstdio>
 2 #include <cctype>
 3 #include <cstring>
 4 #include <algorithm>
 5 #define gc() getchar()
 6 const int N=152*72,S=26;
 7 
 8 int n;
 9 char s[152][72],p[1000005];
10 
11 struct AC_Automaton
12 {
13     int tot,son[N][27],fail[N],val[N],las[N],q[N],tm[152];
14     void Init(){
15         tot=0, memset(son,0,sizeof son), memset(val,0,sizeof val);
16     }
17     void Insert(char *s,int pos)
18     {
19         int l=strlen(s),x=0;
20         for(int id,i=0; i<l; ++i)
21         {
22             id=s[i]-'a';
23             if(!son[x][id]) son[x][id]=++tot;
24             x=son[x][id];
25         }
26         val[x]=pos;
27     }
28     void Build()
29     {
30         int h=0,t=0;
31         for(int i=0; i<S; ++i)
32             if(son[0][i]) fail[son[0][i]]=0,q[t++]=son[0][i];
33         while(h<t)
34         {
35             int x=q[h++];
36             for(int v,i=0; i<S; ++i)
37                 if(son[x][i])
38                     fail[v=son[x][i]]=son[fail[x]][i],q[t++]=v,las[v]=val[fail[v]]?fail[v]:las[fail[v]];
39                 else son[x][i]=son[fail[x]][i];
40         }
41     }
42     void Query(char *p)
43     {
44         int l=strlen(p),res=0,x=0;
45         memset(tm,0,sizeof tm);
46         for(int i=0; i<l; ++i)
47         {
48             x=son[x][p[i]-'a'];
49             for(int j=x; j; j=las[j]) ++tm[val[j]];
50         }
51         for(int i=1; i<=n; ++i) if(res<tm[i]) res=tm[i];
52         printf("%d\n",res);
53         for(int i=1; i<=n; ++i) if(tm[i]==res) printf("%s\n",s[i]);
54     }
55 }ac;
56 
57 int main()
58 {
59     while(scanf("%d",&n),n){
60         ac.Init();
61         for(int i=1; i<=n; ++i) scanf("%s",s[i]),ac.Insert(s[i],i);
62         ac.Build(), scanf("%s",p), ac.Query(p);
63     }
64     return 0;
65 }
AC Automaton 加强版

其它

Hash

判字符串相等

 粘个代码 POJ.2758.Checking the Text(Hash 二分答案)

 1 /*
 2 题意:给定一个字符串,有两种操作:在字符串中插入一个字符、询问某两个位置开始的LCP的长度 
 3 
 4 处理出Hash,LCP可以通过 二分+Hash 解决 
 5 由于修改次数很小,只有200,直接暴力修改重构 Hash 
 6 
 7 长度起名叫len,不要再用l了。。 
 8 */
 9 #include<cstdio>
10 #include<cstring>
11 #include<algorithm>
12 #define ULL unsigned long long
13 using namespace std;
14 const int N=51000,base=131;
15 
16 int n,len,pos[N];
17 char s[N];
18 ULL pw[N],hs[N];
19 
20 void Init(int fr)
21 {
22     for(int i=fr;i<=len;++i)
23         hs[i]=hs[i-1]*base+s[i];
24 }
25 ULL Get_Hash(int l,int r)
26 {
27     return hs[r]-hs[l-1]*pw[r-l+1];
28 }
29 int Solve(int x,int y)
30 {
31     int l=0,r=len-max(x,y)+1,m;
32     while(l<=r)
33     {
34         m=l+r>>1;
35         if(Get_Hash(x,x+m-1)==Get_Hash(y,y+m-1)) l=m+1;
36         else r=m-1;
37     }
38     return r;
39 }
40 
41 int main()
42 {
43 //    freopen("2758.in","r",stdin);
44 
45     pw[0]=1;
46     for(int i=1;i<N;++i)
47         pw[i]=pw[i-1]*base;
48     
49     scanf("%s",s+1);
50     n=len=strlen(s+1);
51     Init(1);
52     for(int i=1;i<=n;++i)
53         pos[i]=i;
54     int t,a,b;char opt[5];
55     scanf("%d",&t);
56     while(t--)
57     {
58         scanf("%s",opt);
59         if(opt[0]=='Q')
60         {
61             scanf("%d%d",&a,&b);
62             printf("%d\n",Solve(pos[a],pos[b]));
63         }
64         else
65         {
66             scanf("%s%d",opt,&a);
67             ++len;
68             if(a>len) a=len;
69             memcpy(s+a+1,s+a,(len-a)*sizeof(char));
70             s[a]=opt[0];
71             for(int i=n;pos[i]>=a;--i)//每一位后移,暴力处理 
72                 ++pos[i];
73             Init(a);
74         }
75     }
76     return 0;
77 }
Hash+二分

莫队

 

带修改莫队

 

01分数规划

 

posted @ 2018-04-04 15:37  SovietPower  阅读(335)  评论(0编辑  收藏  举报