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 }
欧拉函数:
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 }
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 }
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 }
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 }
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 }
浙公网安备 33010602011771号