持续更新中……
快速幂
1 int mul(int x,int n,int mod){ 2 int ans=mod!=1; 3 for(x%=mod;n;n>>=1,x=x*x%mod) 4 if(n&1) ans=ans*x%mod; 5 return ans; 6 }
LCA
1 //Luogu P3379 LCA模板 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 const int N=1e6+5; 6 int n,m,s,x,y,nxt[N],hd[N],to[N],cnt,dep[N],f[N][30]; 7 int add(int x,int y){ 8 nxt[++cnt]=hd[x],hd[x]=cnt,to[cnt]=y; 9 nxt[++cnt]=hd[y],hd[y]=cnt,to[cnt]=x; 10 } 11 void dfs(int x,int fa){ 12 dep[x]=dep[fa]+1; 13 for(int i=0;i<=19;i++) 14 f[x][i+1]=f[f[x][i]][i]; 15 for(int i=hd[x];i;i=nxt[i]){ 16 int y=to[i]; 17 if(y==fa) continue; 18 f[y][0]=x,dfs(y,x); 19 } 20 } 21 int lca(int x,int y){ 22 if(dep[x]<dep[y]) swap(x,y); 23 for(int i=20;i>=0;i--){ 24 if(dep[f[x][i]]>=dep[y]) x=f[x][i]; 25 if(x==y) return x; 26 } 27 for(int i=20;i>=0;i--) 28 if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i]; 29 return f[x][0]; 30 } 31 int main(){ 32 //freopen(".in","r",stdin); 33 //freopen(".out","w",stdout); 34 scanf("%d%d%d",&n,&m,&s); 35 for(int i=1;i<n;i++){ 36 scanf("%d%d",&x,&y); 37 add(x,y); 38 } 39 dfs(s,0); 40 while(m--){ 41 scanf("%d%d",&x,&y); 42 printf("%d\n",lca(x,y)); 43 } 44 return 0; 45 }
最小生成树 Kruskal
1 //Luogu P3366 最小生成树模板 2 #include<bits/stdc++.h> 3 #define int long long 4 using namespace std; 5 const int N=5010,M=2e5+5; 6 int m,n,ans,cnt,f[N],x,y; 7 struct node{ 8 int u,v,d; 9 }a[M]; 10 bool cmp(node x,node y){ 11 return x.d<y.d; 12 } 13 int get(int u){ 14 return f[u]==u?u:f[u]=get(f[u]); 15 } 16 void kruskal(){ 17 sort(a+1,a+1+m,cmp); 18 for(int i=1;i<=m;i++){ 19 if(cnt==n-1) break; 20 x=get(a[i].u),y=get(a[i].v); 21 if(x!=y) ans+=a[i].d,f[x]=y,++cnt; 22 } 23 } 24 signed main(){ 25 //freopen(".in","r",stdin); 26 //freopen(".out","w",stdout); 27 scanf("%lld%lld",&n,&m); 28 for(int i=1;i<=n;i++) 29 f[i]=i; 30 for(int i=1;i<=m;i++) 31 scanf("%lld%lld%lld",&a[i].u,&a[i].v,&a[i].d); 32 kruskal(); 33 if(cnt!=n-1) printf("No\n"); 34 else printf("%lld\n",ans); 35 return 0; 36 }
并查集
1 //Luogu P3367 并查集模板 2 #include<bits/stdc++.h> 3 #define int long long 4 using namespace std; 5 const int N=10010; 6 int n,m,z,x,y,f[N]; 7 int get(int u){ 8 return f[u]==u?u:f[u]=get(f[u]); 9 } 10 signed main() 11 { 12 //freopen(".in","r",stdin); 13 //freopen(".out","w",stdout); 14 scanf("%lld%lld",&n,&m); 15 for(int i=1;i<=n;i++) f[i]=i; 16 for(int i=1;i<=m;i++){ 17 scanf("%lld%lld%lld",&z,&x,&y); 18 if(z==1) f[get(x)]=get(y); 19 if(z==2) get(x)==get(y)?printf("Y\n"):printf("N\n"); 20 } 21 return 0; 22 }
ST表
1 //LOJ#10120 求每个长度为k区间内最大和最小值 2 #include<iostream> 3 #include<algorithm> 4 using namespace std; 5 const int N=1e5+5,logN=17; 6 int n,m,x,y,log[N],f[N][logN+1],z[N][logN+1],a[N],k; 7 int main(){ 8 //freopen(".in","r",stdin); 9 //freopen(".out","w",stdout); 10 scanf("%d%d",&n,&m); 11 for(int i=1;i<=n;i++) 12 scanf("%d",&a[i]); 13 log[0]=-1; 14 for(int i=1;i<=n;i++) 15 f[i][0]=z[i][0]=a[i],log[i]=log[i>>1]+1; 16 for(int j=1;j<=logN;j++) 17 for(int i=1;i+(1<<j)-1<=n;i++){ 18 f[i][j]=max(f[i][j-1],f[i+(1<<j-1)][j-1]); 19 z[i][j]=min(z[i][j-1],z[i+(1<<j-1)][j-1]); 20 } 21 for(int i=1;i<=n-m+1;i++){ 22 x=i,y=i+m-1; 23 k=log[y-x+1]; 24 printf("%d %d\n",max(f[x][k],f[y-(1<<k)+1][k]),min(z[x][k],z[y-(1<<k)+1][k])); 25 } 26 return 0; 27 }