• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
mika-mika
世界第一的兔子殿下。
博客园       新随笔    联系   管理     

mika的模板库

各种板子&持续更新!

二分图最大匹配:

1.匈牙利算法:注意dfs中是dfs(c[w[i]]),搜索的是与之匹配的点。

 1 #include<cstdio>
 2 #include<cstring>
 3 
 4 int n,m,x,y,fi[100001],w[200001],ne[200001],cnt,c[100001],ans;
 5 bool b[100001];
 6 
 7 void add(int u,int v)
 8 {
 9     w[++cnt]=v;ne[cnt]=fi[u];fi[u]=cnt;
10 }
11 
12 bool dfs(int u)
13 {
14     for(int i=fi[u];i;i=ne[i])
15       if(!b[w[i]])
16       {
17         b[w[i]]=1;
18         if(!c[w[i]] || dfs(c[w[i]]))
19         {
20             c[w[i]]=u;return 1;
21         }
22       }
23     return 0;
24 }
25 
26 int main()
27 {
28     while(scanf("%d",&n)!=EOF)
29     {
30         scanf("%d",&m);cnt=0;
31         memset(fi,0,sizeof(fi));
32         memset(c,0,sizeof(c));
33         for(int i=1;i<=m;i++) scanf("%d%d",&x,&y),add(x,y);
34         for(int i=1;i<=n;i++)
35         {
36             memset(b,0,sizeof(b));
37             if(dfs(i)) ans++;
38         }
39         printf("%d\n",ans);
40     }
41     return 0;
42 }
匈牙利算法

2.dinic算法:速度优于匈牙利算法,但是加边时需要区分两边的点。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<queue>
 5 using namespace std;
 6 
 7 int n,m,x,y,fi[200005],w[400005],ne[400005],v[400005],cnt,ans,dis[200005];
 8 
 9 queue<int> q;
10 
11 int read()
12 {
13     int x=0,f=1;char ch=getchar();
14     while(ch<'0' || ch>'9') {if(ch=='-') f=-1;ch=getchar();}
15     while(ch>='0' && ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
16     return x*f;
17 }
18 
19 void add(int u,int vv,int val)
20 {
21     w[++cnt]=vv;ne[cnt]=fi[u];fi[u]=cnt;v[cnt]=val;
22     w[++cnt]=u;ne[cnt]=fi[vv];fi[vv]=cnt;v[cnt]=val;
23 }
24 
25 bool bfs()
26 {
27     memset(dis,-1,sizeof(dis));
28     dis[0]=0;q.push(0);
29     while(!q.empty())
30     {
31         int k=q.front();q.pop();
32         for(int i=fi[k];i;i=ne[i])
33           if(v[i]>0 && dis[w[i]]==-1)
34           {
35               dis[w[i]]=dis[k]+1;
36               q.push(w[i]);
37           }
38     }
39     return dis[n*2+1]==-1 ? 0:1;
40 }
41 
42 int dfs(int u,int vv)
43 {
44     if(u==n*2+1) return vv;
45     int kkz,now=0;
46     for(int i=fi[u];i;i=ne[i])
47       if(dis[w[i]]==dis[u]+1 && v[i]>0 && (kkz=dfs(w[i],min(vv-now,v[i]))))
48       {
49         v[i]-=kkz;v[i^1]+=kkz;now+=kkz;
50         if(now==vv) return now;
51       }
52     if(!now) dis[u]=-1;
53     return now;
54 }
55 
56 int main()
57 {
58     while(scanf("%d",&n)!=EOF)
59     {
60         m=read();cnt=1;ans=0;
61         memset(fi,0,sizeof(fi));
62         for(int i=1;i<=m;i++) x=read(),y=read(),add(x,y+n,1);
63         for(int i=1;i<=n;i++) add(0,i,1),add(i+n,2*n+1,1);
64         while(bfs()) ans+=dfs(0,999999999);
65         printf("%d\n",ans);
66     }
67     return 0;
68 }
dinic算法

 

欧拉函数:

1.公式:euler(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…(1-1/pn),其中p1,p2……pn为x的所有素因数,x是不为0的整数。

1 ans=n;
2 for(int i=2;i*i<=n;i++)
3   if(!(n%i))
4   {
5     while(!(n%i)) n/=i;ans=ans/i*(i-1);  
6   }
7 if(n!=1) ans=ans/n*(n-1);
公式

2.线性筛:

 1 phi[1]=1;
 2 for(int i=2;i<=n;i++)
 3 {
 4     if(!b[i]) a[++a[0]]=i,phi[i]=i-1;
 5     for(int j=1;a[j]*i<=n && j<=a[0];j++)
 6     {
 7         b[i*a[j]]=1;
 8         if(!(i%a[j]))
 9         {
10             phi[i*a[j]]=phi[i]*a[j];break;
11         }
12         phi[i*a[j]]=phi[i]*phi[a[j]];
13     }
14 }
线性筛

 

莫比乌斯函数:

 1 u[1]=1;
 2 for(int i=2;i<=n;i++)
 3 {
 4     if(!b[i]) q[++q[0]]=i,u[i]=-1;
 5     for(int j=1;j<=q[0] && i*q[j]<=n;j++)
 6     {
 7         b[i*q[j]]=1;
 8         if(!(i%q[j]))
 9         {
10             u[i*q[j]]=0;break;
11         }
12         u[i*q[j]]=-u[i];
13     }
14 }
莫比乌斯函数

 

线性基:线性基的异或和是序列的最大异或和。

1.单区间:

 1 for(int i=1;i<=n;i++)
 2   for(int j=29;~i;i--)
 3     if(a[i]&(1<<j))
 4     {
 5         if(f[j]) a[i]^=f[j];
 6         else
 7         {
 8             f[j]=a[i];break;
 9         }
10     }
单区间线性基

2.多区间:f[i]表示区间[i,n]的线性基。

 1 struct node{
 2     int x,id;
 3 }f[N][30],tmp;
 4 
 5 for(int i=n;i;i--)
 6 {
 7     memcpy(f[i],f[i+1],sizeof(f[i+1]));
 8     tmp=(node){a[i],i};
 9     for(int j=29;~j;j--)
10       if(tmp.x&(1<<j))
11       {
12           if(!f[i][j].x) swap(tmp,f[i][j]);
13           else
14           {
15               if(f[i][j].id>tmp.id) swap(tmp,f[i][j]);
16               tmp.x^=f[i][j].x;
17           }
18       }
19 }
多区间线性基

 

扩展欧几里得算法解二元一次方程:

 1 int gcd(int a,int b,int &x,int &y)
 2 {
 3     if(!b)
 4     {
 5         x=1;y=0;return a;
 6     }
 7     int k=gcd(b,a%b,x,y),z=y;
 8     y=x-a/b*y;x=z;
 9     return k;
10 }
11 
12 void getans(int a,int b,int c,int &x,int &y)
13 {
14     int k=c/gcd(a,b,x,y);
15     x*=k;y*=k;
16 }
二元一次方程

 

FFT:

1.使用STL里面的complex,比较方便:

 1 #define E complex<double>
 2 #define pi acos(-1)
 3 
 4 void fft(E *u,int v)
 5 {
 6     for(int i=0;i<n;i++) if(r[i]>i) swap(u[r[i]],u[i]);
 7     for(int i=1;i<n;i<<=1)
 8     {
 9         E wn(cos(pi/i),v*sin(pi/i));
10         for(int j=0;j<n;j+=(i<<1))
11         {
12             E w(1,0);
13             for(int k=0;k<i;k++,w=w*wn)
14             {
15                 E x=u[j+k],y=u[i+j+k]*w;
16                 u[j+k]=x+y;u[i+j+k]=x-y;
17             }
18         }
19     }
20     if(v==-1) for(int i=0;i<n;i++) u[i]/=n;
21 }
22 
23 int main()
24 {
25     n=read();for(int i=1;i<=n;i++) a[i]=read();
26     m=read();for(int i=1;i<=m;i++) b[i]=read();
27     m+=n;
28     for(n=1;n<=m;n<<=1) l++;
29     for(int i=0;i<n;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
30     fft(a,1);fft(b,1);
31     for(int i=1;i<n;i++) a[i]=a[i]*b[i];
32     fft(a,-1);
33     for(int i=0;i<n;i++) c[i]=(int)(a[i].real()+0.5);
34 }
STLcomplex FFT

2.struct定义complex型,要比STL快:

 1 #define pi acos(-1)
 2 
 3 int n,m,l,r[N];
 4 
 5 struct E{
 6     double a,b;
 7     E() {}
 8     E(double aa,double bb):a(aa),b(bb) {}
 9     E operator + (const E&u) const {return E(a+u.a,b+u.b);}
10     E operator - (const E&u) const {return E(a-u.a,b-u.b);}
11     E operator * (const E&u) const {return E(a*u.a-b*u.b,a*u.b+b*u.a);}
12     E operator !() const {return E(a,-b);}
13 }a[N],b[N];
14 
15 void fft(E *u,int v)
16 {
17     for(int i=0;i<n;i++) if(r[i]>i) swap(u[r[i]],u[i]);
18     for(int i=1;i<n;i<<=1)
19     {
20         E wn(cos(pi/i),v*sin(pi/i));
21         for(int j=0;j<n;j+=(i<<1))
22         {
23             E w(1,0);
24             for(int k=0;k<i;k++,w=w*wn)
25             {
26                 E x=u[j+k],y=u[i+j+k]*w;
27                 u[j+k]=x+y;u[i+j+k]=x-y;
28             }
29         }
30     }
31     if(v==-1) for(int i=0;i<n;i++) u[i].a/=n;
32 }
33 
34 int main()
35 {
36     scanf("%d%d",&n,&m);
37     for(int i=1;i<=n;i++) scanf("%d",&a[i].a);
38     for(int i=1;i<=n;i++) scanf("%d",&b[i].a);
39     m+=n;
40     for(n=1;n<=m;n<<=1) l++;
41     for(int i=0;i<l;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
42     fft(a,1);fft(b,1);
43     for(int i=0;i<n;i++) a[i]=a[i]*b[i];
44     fft(a,-1);
45     for(int i=0;i<n;i++) c[i]=(int){a[i].a+0.5};
46 }
手写complex FFT

 

KDtree:

1.求最小值,带更新:

  1 #include<cstdio>  
  2 #include<iostream>  
  3 #include<algorithm>  
  4 using namespace std;  
  5 #define inf 999999999  
  6   
  7 int n,m,opt,x,y,root,kkz,ans;  
  8   
  9 struct node{  
 10     int a[2],mx[2],mn[2],l,r;  
 11 }a[500001],c[1000001],kkzv,T;  
 12   
 13 int read()  
 14 {  
 15     int x=0,f=1;char ch=getchar();  
 16     while(ch<'0' || ch>'9') {if(ch=='-') f=-1;ch=getchar();}  
 17     while(ch>='0' && ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}  
 18     return x*f;  
 19 }  
 20   
 21 bool operator < (node u,node v)  
 22 {  
 23     return u.a[kkz]<v.a[kkz];  
 24 }  
 25   
 26 int abs(int u)  
 27 {  
 28     return u<0 ? -u:u;  
 29 }  
 30   
 31 int dis(node u,node v)  
 32 {  
 33     return abs(u.a[0]-v.a[0])+abs(u.a[1]-v.a[1]);  
 34 }  
 35   
 36 void update(int u)  
 37 {  
 38     node l=c[c[u].l],r=c[c[u].r];  
 39     for(int i=0;i<2;i++)  
 40     {  
 41         if(c[u].l) c[u].mx[i]=max(c[u].mx[i],l.mx[i]),c[u].mn[i]=min(c[u].mn[i],l.mn[i]);  
 42         if(c[u].r) c[u].mx[i]=max(c[u].mx[i],r.mx[i]),c[u].mn[i]=min(c[u].mn[i],r.mn[i]);  
 43     }  
 44 }  
 45   
 46 int build(int l,int r,int now)  
 47 {  
 48     kkz=now;  
 49     int mid=l+r>>1;  
 50     nth_element(a+l,a+mid,a+r+1);  
 51     c[mid]=a[mid];  
 52     for(int i=0;i<2;i++) c[mid].mn[i]=c[mid].mx[i]=c[mid].a[i];  
 53     if(l<mid) c[mid].l=build(l,mid-1,now^1);  
 54     if(r>mid) c[mid].r=build(mid+1,r,now^1);  
 55     update(mid);  
 56     return mid;   
 57 }  
 58   
 59 int get(int k,node u)  
 60 {  
 61     int now=0;  
 62     for(int i=0;i<2;i++) now+=max(0,c[k].mn[i]-u.a[i]);  
 63     for(int i=0;i<2;i++) now+=max(0,u.a[i]-c[k].mx[i]);  
 64     return now;  
 65 }  
 66   
 67 void insert(int k,int now)  
 68 {  
 69     if(T.a[now]>=c[k].a[now])  
 70     {  
 71         if(c[k].r) insert(c[k].r,now^1);  
 72         else   
 73         {  
 74             c[k].r=++n;c[n]=T;  
 75             for(int i=0;i<2;i++) c[n].mn[i]=c[n].mx[i]=c[n].a[i];  
 76         }  
 77     }  
 78     else   
 79     {  
 80         if(c[k].l) insert(c[k].l,now^1);  
 81         else   
 82         {  
 83             c[k].l=++n;c[n]=T;  
 84             for(int i=0;i<2;i++) c[n].mn[i]=c[n].mx[i]=c[n].a[i];  
 85         }  
 86     }  
 87     update(k);  
 88 }  
 89   
 90 void query(int k)  
 91 {  
 92     int d,dl=inf,dr=inf;  
 93     d=dis(c[k],T);  
 94     ans=min(ans,d);  
 95     if(c[k].l) dl=get(c[k].l,T);  
 96     if(c[k].r) dr=get(c[k].r,T);  
 97     if(dl<dr)  
 98     {  
 99         if(dl<ans) query(c[k].l);  
100         if(dr<ans) query(c[k].r);  
101     }  
102     else  
103     {  
104         if(dr<ans) query(c[k].r);  
105         if(dl<ans) query(c[k].l);  
106     }  
107 }  
108   
109 int query(node p)  
110 {  
111     ans=inf;T=p;  
112     query(root);  
113     return ans;  
114 }  
115   
116 int main()  
117 {  
118     n=read();m=read();  
119     for(int i=1;i<=n;i++) a[i].a[0]=read(),a[i].a[1]=read();  
120     root=build(1,n,0);  
121     while(m--)  
122     {  
123         opt=read();kkzv.a[0]=read();kkzv.a[1]=read();  
124         if(opt==1) T=kkzv,insert(root,0);  
125         else printf("%d\n",query(kkzv));  
126     }  
127     return 0;  
128 }  
min带修改

2.求最大值的cal函数:

1 int cal(int u)
2 {
3     int now=0;
4     for(int k=0;k<2;k++) now+=max(abs(c[u].mx[k]-tmp.a[k]),abs(c[u].mn[k]-tmp.a[k]));
5     return now;
6 }
cal_max函数

 

KMP:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 using namespace std;
 5 
 6 const int N=1000001;
 7 
 8 int t,n,next[N],len1,len2;
 9 char s1[N],s2[N];
10 
11 int cal()
12 {
13     int k=0,ans=0;
14     for(int i=2;i<=len1;i++)
15     {
16         while(k>0 && s1[k+1]!=s1[i]) k=next[k];
17         if(s1[k+1]==s1[i]) k++;
18         next[i]=k;
19     }
20     k=0;
21     for(int i=1;i<=len2;i++)
22     {
23         while(k>0 && s1[k+1]!=s2[i]) k=next[k];
24         if(s1[k+1]==s2[i]) k++;
25         if(k==len1) ans++,k=next[k];
26     }
27     return ans;
28 }
29 
30 int main()
31 {
32     scanf("%d",&t);
33     while(t--)
34     {
35         scanf("%s%s",s1+1,s2+1);
36         len1=strlen(s1+1);len2=strlen(s2+1);
37         printf("%d\n",cal());
38     }
39     return 0;
40 }
KMP

 

posted @ 2017-05-31 17:18  mika-mika  阅读(184)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3