个中模板
坑:需要填的模板:hungary,AC,高斯消元,并查集,dinic,fft,堆,tarjian,kruskal,fast_mi
学习jjh同学搞个模板集合
对拍:
1 @echo off 2 3 set path=C:\Windows\System32 4 5 :loop 6 7 data.exe 8 PIA.exe 9 ddd.exe 10 11 fc PIA.out ddd.out 12 13 if not errorlevel 1 goto loop 14 15 pause 16 17 goto loop
后缀数组:
1 int n; char s[1100]; 2 int rank[1100],height[1100]; 3 int cnt[1100],cnt_rank[1100]; 4 int rank1[1100],rank2[1100]; 5 int SA[1100],temp_SA[1100]; 6 void get_suffix_rank(){ 7 memset(cnt,0,sizeof(cnt)); 8 for(int i=0;i<n;i++) cnt[s[i]]++; 9 for(int i=1;i<=210;i++) cnt[i]+=cnt[i-1]; 10 for(int i=0;i<n;i++) rank[i]=cnt[s[i]]-1; 11 for(int l=1;l<n;l*=2){ 12 for(int i=0;i<n;i++){ rank1[i]=rank[i]; rank2[i]=(i+l<n) ? rank[i+l] : 0;} 13 memset(cnt_rank,0,sizeof(cnt_rank)); 14 for(int i=0;i<n;i++) cnt_rank[rank2[i]]++; 15 for(int i=1;i<n;i++) cnt_rank[i]+=cnt_rank[i-1]; 16 for(int i=n-1;i>=0;i--) temp_SA[--cnt_rank[rank2[i]]]=i; 17 memset(cnt_rank,0,sizeof(cnt_rank)); 18 for(int i=0;i<n;i++) cnt_rank[rank1[i]]++; 19 for(int i=1;i<n;i++) cnt_rank[i]+=cnt_rank[i-1]; 20 for(int i=n-1;i>=0;i--) SA[--cnt_rank[rank1[temp_SA[i]]]]=temp_SA[i]; 21 rank[SA[0]]=0; 22 for(int i=1;i<n;i++){ 23 rank[SA[i]]=rank[SA[i-1]]; 24 rank[SA[i]]+=(rank1[SA[i]]!=rank1[SA[i-1]] || rank2[SA[i]]!=rank2[SA[i-1]]); 25 } 26 } 27 } 28 void get_height(){ 29 int _l=0; 30 for(int i=0;i<n;i++)if(rank[i]){ 31 int j=SA[rank[i]-1]; 32 while(i+_l<n && j+_l<n && s[i+_l]==s[j+_l]) _l++; 33 height[rank[i]]=_l; 34 _l-=(_l>0); 35 } 36 } 37 int main(){//freopen("ddd.in","r",stdin); 38 scanf("%s",&s); n=strlen(s); s[n++]='$'; 39 get_suffix_rank(); get_height();
筛欧拉函数:
1 void shai(){ 2 memset(kang,0,sizeof(kang)); 3 phi[1]=1; 4 for(int i=2;i<=n;i++){ 5 if(!kang[i]){ phi[i]=i-1; zhi[++ztop]=i;} 6 for(int j=1;j<=ztop && i*zhi[j]<=n;j++){ 7 kang[i*zhi[j]]=true; 8 if(i%zhi[j]==0){ phi[i*zhi[j]]=phi[i]*zhi[j]; break;} 9 phi[i*zhi[j]]=phi[i]*phi[zhi[j]]; 10 } 11 } 12 }
SPFA:
1 struct ddd{int next,y,value;}e[210000];int LINK[110000],ltop=0; 2 int dui[1100000],tou=0; 3 bool visited[110000]; 4 int f[110000]; 5 void SPFA(){ 6 memset(visited,0,sizeof(visited)); 7 memset(f,10,sizeof(f)); 8 dui[tou=1]=s; f[s]=0; 9 for(int k=1;k<=tou;k++){ 10 visited[dui[k]]=false; 11 for(int i=1;i<=LINK[x];i++) 12 if(f[e[i].y] < f[dui[k]]+e[i].value){ 13 f[e[i].y]=f[dui[k]]+e[i].value; 14 if(!visited[e[i].y]) dui[++tou]=e[i].y,visited[e[i].y]=true; 15 } 16 } 17 }
kmp:(网上很多版本,这个是下标从0开始的)
1 int j=-1; next[0]=-1; 2 for(int i=1;i<lb;i++){ 3 while(j>-1 && b[j+1]!=b[i]) j=next[j]; 4 if(b[j+1]==b[i]) j++; 5 next[i]=j; 6 } 7 j=-1; 8 for(int i=1;i<la;i++){ 9 while(j>-1 && b[j+1]!=a[i]) j=next[j]; 10 if(b[j+1]==a[i]) j++; 11 if(j==lb-1){ cout<<i-lb<<endl; j=next[j];}//继续往下找下一个匹配 12 }
归并排序求逆序对:
1 int a[1100000]; 2 int c[1100000],ctou=0; 3 int bowl=0; 4 void bing(int _left,int _right){ 5 int mid=(_left+_right)/2; 6 int i=_left,j=mid+1; cout=_left-1; 7 while(i<=mid && j<=_right){ 8 if(a[i]>a[j]){ c[++ctou]=a[j++]; bowl+=mid-i+1;} 9 else c[++ctou]=a[i++]; 10 } 11 while(i<=mid) c[++ctou]=a[i++]; 12 while(j<=_right) c[++cout]=a[j++]; 13 for(int i=_left;i<=_right;i++) a[i]=c[i]; 14 } 15 void gui(int _left,int _right){ 16 if(_left<_right){ 17 int mid=(_left+_right)/2; 18 gui(_left,mid),gui(mid+1,_right); 19 bing(_left,_right); 20 } 21 }
剖:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 int read(){int z=0,mark=1; char ch=getchar(); 8 while(ch<'0'||ch>'9'){if(ch=='-')mark=-1; ch=getchar();} 9 while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0'; ch=getchar();} 10 return z*mark; 11 } 12 struct ddd{int next,y,value;}e[21000];int LINK[11000],ltop=0; 13 inline void insert(int x,int y,int z){e[++ltop].next=LINK[x];LINK[x]=ltop;e[ltop].y=y;e[ltop].value=z;} 14 int n; char sq[10]; 15 struct cdd{int x,y,value;}bian[11000]; int ower[11000];//这里要这个是因为改的是边的权值,需要转移到up_value上 16 int father[11000],size[11000],deep[11000],up_value[11000],big_child[11000]; 17 int dfs_xv[11000],fan_xv[11000],xv_cnt=0,top[11000]; 18 void dfs1(int x,int _deep,int _father){ 19 father[x]=_father,deep[x]=_deep; size[x]=1;//注意size初始化 20 int max_size=0,max_child=0; 21 for(int i=LINK[x];i;i=e[i].next)if(e[i].y!=father[x]){ 22 dfs1(e[i].y,deep[x]+1,x); 23 up_value[e[i].y]=e[i].value; 24 size[x]+=size[e[i].y]; 25 if(size[e[i].y]>max_size) max_size=size[e[i].y],max_child=e[i].y; 26 } 27 big_child[x]=max_child; 28 } 29 void dfs2(int x,int _top){ 30 top[x]=_top; dfs_xv[++xv_cnt]=x; fan_xv[x]=xv_cnt; 31 if(big_child[x]) dfs2(big_child[x],_top); 32 for(int i=LINK[x];i;i=e[i].next)if(e[i].y!=father[x] && e[i].y!=big_child[x])//憋忘了father 33 dfs2(e[i].y,e[i].y); 34 } 35 struct dcd{int sleft,sright,mid,svalue;}tree[110000]; 36 void get_SegmentTree(int x,int _left,int _right){ 37 tree[x].sleft=_left,tree[x].sright=_right,tree[x].mid=(_left+_right)>>1; 38 if(_left==_right) tree[x].svalue=up_value[dfs_xv[_left]];//注意这里是dfs_xv 39 else{ 40 get_SegmentTree(x<<1,_left,tree[x].mid),get_SegmentTree(x<<1|1,tree[x].mid+1,_right); 41 tree[x].svalue=max(tree[x<<1].svalue,tree[x<<1|1].svalue); 42 } 43 } 44 int search(int x,int _left,int _right){ 45 if(tree[x].sleft==_left && tree[x].sright==_right) return tree[x].svalue; 46 else if(_left<=tree[x].mid && _right>tree[x].mid) return max(search(x<<1,_left,tree[x].mid),search(x<<1|1,tree[x].mid+1,_right)); 47 else if(_right<=tree[x].mid) return search(x<<1,_left,_right); 48 else return search(x<<1|1,_left,_right); 49 } 50 void buff(int x,int _id,int _value){ 51 if(tree[x].sleft==_id && tree[x].sright==_id) tree[x].svalue=_value; 52 else{ 53 if(_id<=tree[x].mid) buff(x<<1,_id,_value); 54 else buff(x<<1|1,_id,_value); 55 tree[x].svalue=max(tree[x<<1].svalue,tree[x<<1|1].svalue); 56 } 57 } 58 int pa(int x,int y){ 59 int maxx=0; 60 int fa=top[x],fb=top[y]; 61 while(fa!=fb){ 62 if(deep[fa]<deep[fb]) swap(fa,fb),swap(x,y); 63 maxx=max(maxx,search(1,fan_xv[fa],fan_xv[x]));//注意x 64 x=father[fa]; fa=top[x]; 65 } 66 if(deep[x]>deep[y]) swap(x,y); 67 if(x!=y) maxx=max(maxx,search(1,fan_xv[x]+1,fan_xv[y]));//注意拐点,注意判断 68 return maxx; 69 } 70 int main(){//freopen("ddd.in","r",stdin); 71 int T;cin>>T;while(T --> 0){//趋向于 72 ltop=0; xv_cnt=0; memset(LINK,0,sizeof(LINK));//注意多组数据初始化,尤其是LINK 73 cin>>n; 74 int _left,_right,_value; 75 for(int i=1;i<n;i++){ 76 _left=read(),_right=read(),_value=read(); 77 insert(_left,_right,_value),insert(_right,_left,_value); 78 bian[i].x=_left,bian[i].y=_right,bian[i].value=_value; 79 } 80 dfs1(1,1,0),dfs2(1,1),get_SegmentTree(1,1,n); 81 for(int i=1;i<n;i++) ower[i]=(bian[i].x==father[bian[i].y]) ? bian[i].y : bian[i].x; 82 for(;;){ 83 scanf("%s",sq); if(sq[0]=='D') break; 84 _left=read(),_right=read(); 85 if(sq[0]=='Q') printf("%d\n",pa(_left,_right)); 86 else buff(1,fan_xv[ower[_left]],_right);//注意反序 87 } 88 } 89 return 0; 90 }
msc求完美消除序列:
1 void mcs(){ 2 for(int i=n;i;i--){ 3 int now=0; 4 for(int j=1;j<=n;j++)//注意这个label最大的点并不是和i相邻的点,而是全局点 5 if(label[j]>=label[now] && !visited[j]) now=j;//这个循环一搞不就变成n^2的了??? 6 visited[now]=true; 7 peo[i]=now; 8 for(int j=LINK[now];j;j=e[j].next) 9 label[e[j].y]++; 10 } 11 }
二分图染色:
1 memset(color,-1,sizeof(color)); 2 int color[1100]; 3 bool dfs(int x,int y){ 4 if(color[x]!=-1 && color[x]==color[y]) return false; 5 if(color[x]==!color[y]) return true;//因为color[y]只能是0或1,所以不用判断color[x]!=-1 6 color[x]=!color[y]; 7 for(int i=LINK[x];i;i=e[i].next)if(e[i].y!=y && !dfs(e[i].y,x)) return false;//注意要判断e[i].y!=y,否则很有可能陷入e[i].y和y之间的死循环 8 return true; 9 } 10 color[0]=0; 11 for(int i=1;i<=n;i++)if(color[i]==-1 && !dfs(i,0)) return 0;
高精度:(里面全是高精和单精运算,乘法和加法都差不多,双高精除法这个东西太玄了)
1 int c[1100000]; 2 void copy(int *x,int *y){memset(y,0,sizeof(y)); y[0]=x[0]; for(int i=1;i<=x[0];i++) y[i]=x[i];} 3 void cheng(int *x,int z){ 4 for(int i=1;i<=x[0];i++) x[i]*=z; 5 for(int i=1;i<=x[0];i++) x[i+1]+=x[i]/ss,x[i]%=ss; 6 while(x[x[0]+1]){ x[0]++; x[x[0]+1]+=x[x[0]]/ss,x[x[0]]%=ss;} 7 } 8 bool bi(int *x,int *y){ 9 if(x[0]>y[0]) return true; 10 if(x[0]<y[0]) return false; 11 for(int i=x[0];i>=1;i--)if(x[i]!=y[i]) return x[i]>y[i]; 12 return true; 13 } 14 void chu(int *x,int *y,int z){//因为除的数<10000,刚好在万进制范围内,就直接除单精了 15 copy(y,c); 16 x[0]=c[0]-(c[c[0]]<z); 17 for(int i=c[0];i>=1;i--){ 18 x[i]=c[i]/z; 19 c[i-1]+=(c[i]%z)*ss; 20 } 21 for(int i=1;i<=x[0];i++) x[i+1]+=x[i]/ss,x[i]%=ss; 22 while(x[x[0]+1]){ x[0]++; x[x[0]+1]+=x[x[0]]/ss,x[x[0]]%=ss;} 23 } 24 void jia(int *x,int z){ 25 x[1]+=z;//睁大眼看好高精度+单精度怎么写qaq 26 for(int i=1;i<=x[0];i++) x[i+1]+=x[i]/ss,x[i]%=ss; 27 while(x[x[0]+1]){ x[0]++; x[x[0]+1]+=x[x[0]]/ss,x[x[0]]%=ss;} 28 }
fft求高精度乘:(然而我并没有学会一。一,先放个模板慢慢氪)
1 struct cp{ 2 double r,i; 3 cp(double _r=0,double _i=0): r(_r),i(_i){} 4 cp operator+(cp x){return cp(r+x.r,i+x.i);} 5 cp operator-(cp x){return cp(r-x.r,i-x.i);} 6 cp operator*(cp x){return cp(r*x.r-i*x.i,r*x.i+i*x.r);} 7 }; 8 cp a[5100],b[5100],_c[5100],_x,_y,c[5100]; 9 char aa[5100],bb[5100]; int la,lb; 10 int ans[5100],a1[5100],a2[5100],dig[5100]; 11 int rev[5100],N,L; 12 void fft(cp x[],int sign){ 13 for(int i=0;i<N;i++) _c[i]=x[rev[i]]; 14 for(int i=0;i<N;i++) x[i]=_c[i]; 15 for(int i=2;i<=N;i<<=1){ 16 cp wn(cos(2*M_PI/i),sign*sin(2*M_PI/i)); 17 for(int k=0;k<N;k+=i){ 18 cp w(1,0); 19 for(int j=k;j<k+i/2;j++){ 20 _x=x[j]; 21 _y=x[j+i/2]*w; 22 x[j]=_x+_y; 23 x[j+i/2]=_x-_y; 24 w=w*wn; 25 } 26 } 27 } 28 if(sign==-1) 29 for(int i=0;i<N;i++) 30 x[i].r/=N; 31 } 32 int main(){//freopen("ddd.in","r",stdin); 33 scanf("%s%s",aa,bb); la=strlen(aa),lb=strlen(bb); 34 for(N=1,L=0;N<max(la,lb);N<<=1,L++);N<<=1;L++; 35 for(int i=0;i<N;i++){ 36 int l=0; 37 for(int j=i;j;j>>=1) dig[l++]=j&1; 38 for(int j=0;j<L;j++) rev[i]=(rev[i]<<1)|dig[j]; 39 } 40 for(int i=0;i<la;i++) a1[la-i-1]=aa[i]-'0'; 41 for(int i=0;i<lb;i++) a2[lb-i-1]=bb[i]-'0'; 42 for(int i=0;i<N;i++) a[i]=cp(a1[i]); 43 for(int i=0;i<N;i++) b[i]=cp(a2[i]); 44 fft(a,1),fft(b,1); 45 for(int i=0;i<N;i++) c[i]=a[i]*b[i]; 46 fft(c,-1); 47 for(int i=0;i<N;i++) ans[i]=int(c[i].r+0.5); 48 for(int i=0;i<N;i++){ 49 ans[i+1]+=ans[i]/10; 50 ans[i]%=10; 51 } 52 int l=la+lb-1; 53 while(ans[l]==0&&l) l--; 54 for(int i=l;i>=0;i--) printf("%d",ans[i]); 55 cout<<endl; 56 return 0; 57 }