模板大全(仅限个人能力)
模板大全
一·算法部分
(一)排序部分
1.冒泡排序
#include<iostream> #include<cstdio> using namespace std; int n; int a[3000]; int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=1;i<=n-1;i++) for(int j=2;j<=n;j++) if(a[j-1]>a[j])swap(a[j-1],a[j]); for(int i=1;i<=n;i++)printf("%d ",a[i]); }
2.选择排序
#include<iostream> #include<cstdio> using namespace std; int n,a[100001]; int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=2;i<=n;i++) { for(int j=i;j>1;j--) { if(a[j]<a[j-1]) { int temp=a[j]; a[j]=a[j-1]; a[j-1]=temp; } else break; } } for(int i=1;i<=n;i++)printf("%d ",a[i]); }
3.插入排序
#include<iostream> #include<cstdio> using namespace std; int n,a[100001]; int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=2;i<=n;i++) { int l=0,r=i-1; int g=a[i]; while(l<=r) { int mid=(l+r)/2; if(a[mid]>g)r=mid-1; else l=mid+1; } for(int j=i-1;j>=l;j--)a[j+1]=a[j]; a[l]=g; } for(int i=1;i<=n;i++)printf("%d ",a[i]); }
4.归并排序
#include<iostream> #include<cstdio> using namespace std; int n,a[100001]; void up(int l,int mid,int r) { int i=l,num[100001],tot=0,j=mid+1; while(i<=mid&&j<=r) { if(a[i]>a[j])num[++tot]=a[j++]; else num[++tot]=a[i++]; } while(i<=mid)num[++tot]=a[i++]; while(j<=r)num[++tot]=a[j++]; for(int i=1;i<=tot;i++) { a[l++]=num[i]; } } void sep(int l,int r) { if(l==r)return ; int mid=l+(r-l)/2; sep(l,mid); sep(mid+1,r); up(l,mid,r); } int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); sep(1,n); for(int i=1;i<=n;i++)printf("%d ",a[i]); }
5.快速排序(sort)
(二)快速幂
#include<bits/stdc++.h> using namespace std; long long b,p,k; long long ans,bas; int main() { ans=1; cin>>b>>p>>k; int t=p; bas=b; while(p!=0) { if(p & 1 ==1)ans=((ans%k)*(bas%k))%k; bas=((bas%k)*(bas%k))%k; p >>= 1; } cout<<b<<"^"<<t<<" mod "<<k<<"="<<ans%k; }
(三)三分
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<algorithm> using namespace std; int n; double l,r; double a[14]; double calc(double a,double b) { double sum=1; for(int i=1;i<=b;i++)sum*=a; return sum; } int main() { scanf("%d%lf%lf",&n,&l,&r); for(int i=n;i>=0;i--)scanf("%lf",&a[i]); while(l+0.000001<=r) { double lmid=(l+r)/2; double rmid=(lmid+r)/2; double sum1=0,sum2=0; for(int i=n;i>=1;i--)sum1+=a[i]*calc(lmid,i),sum2+=a[i]*calc(rmid,i); sum1+=a[0];sum2+=a[0]; // printf("\nf(%lf)=%lf f(%lf)=%lf \n",lmid,sum1,rmid,sum2); sum1>sum2?r=rmid:l=lmid; } printf("%.5lf",l); }
(四)ST表
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; int a[100010]; int f[100010][60]; int n,m; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); f[i][0]=a[i]; } int LC=floor(log(n)/log(2.0)); for(int j=1;j<=LC;++j) { for(int i=1;i<=n-(1<<j)+1;++i) { f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]); } } for(int i=1;i<=m;i++) { int l,r; scanf("%d%d",&l,&r); int p=floor(log(r-l+1)/log(2)); printf("%d\n",max(f[l][p],f[r-(1<<p)+1][p])); } return 0; }
(五)字符串相关
#include<iostream> #include<cstdio> #include<cstring> using namespace std; char s[11100000]; char new_s[11100000<<1]; int f[11100000<<1]; int ans; int Init() { new_s[0]='$'; int k=1; int p=strlen(s); for(int i=0;i<p;i++) { new_s[k++]=s[i]; new_s[k++]='#'; } new_s[k]='\0'; return k; } int main() { scanf("%s",s); int len=Init(); int id=0,mx=0; for(int i=1;i<len;i++) { f[i]=mx>i?min(f[2*id-i],mx-i):1; while(new_s[i+f[i]]==new_s[i-f[i]])f[i]++; if(i+f[i]>mx)mx=i+f[i],id=i; ans=max(ans,f[i]); } printf("%d",ans-1); // for(int i=1;new_s[i]!='\0';i++)cout<<new_s[i]<<" ";cout<<endl; // for(int i=1;new_s[i]!='\0';i++)cout<<f[i]<<" "; }
#include <iostream> #include <cstring> #include <cstdio> using namespace std; #define N int(1e6+2) #define M int(1e6+2) int n,m,ans,nx[N]; char S[N],T[M]; void getnx() { nx[0]=nx[1]=0; for(int i=2;i<=n;i++) { int p=nx[i-1]; while(p&&S[i]!=S[p+1])p=nx[p]; if(S[i]==S[p+1])nx[i]=p+1; else nx[i]=0; } } int main() { scanf("%s",T+1); scanf("%s",S+1); m=strlen(T+1),n=strlen(S+1); getnx(); int p=0; for(int i=1;i<=m;i++) { while(p&&T[i]!=S[p+1])p=nx[p]; if(T[i]==S[p+1])++p; else p=0; if(p==n)printf("%d\n",i-n+1),p=nx[p]; } for(int i=1;i<=n;i++)printf("%d ",nx[i]); return 0; }
#include<cstdio> #include<cstring> #include<algorithm> #define ull unsigned long long using namespace std; const ull base=233; ull pw[100005],hs[100005]; char S[100005]; int n; void init() { pw[0]=1; for(int i=1;i<=n;i++)pw[i]=pw[i-1]*base; hs[0]=0; for(int i=1;i<=n;i++)hs[i]=hs[i-1]*base+S[i]; } inline ull geths(int l,int r) { return hs[r]-hs[l-1]*pw[r-l+1]; } int main() { return 0; }
(六)网络流
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int edge[1011][1011]; int cx[1001],cy[1001]; bool vis[1011]; int n,m,e,ans; int path(int u) { for(int v=0;v<=m;v++) { if(edge[u][v]&&!vis[v]) { vis[v]=1; if(cy[v]==-1||path(cy[v])) { cx[u]=v; cy[v]=u; return 1; } } } return 0; } int main() { memset(cx,-1,sizeof(cx)); memset(cy,-1,sizeof(cy)); scanf("%d%d%d",&n,&m,&e); int x,y; for(int i=1;i<=e;++i)scanf("%d%d",&x,&y),edge[x][y]=1; for(int i=1;i<=n;i++) { if(cx[i]==-1) { memset(vis,0,sizeof(vis)); ans+=path(i); } } printf("%d",ans); }
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int inf=1e9; int n,m,x,y,z,maxflow,deep[500];//deep深度 struct Edge{ int next,to,dis; }edge[500]; int num_edge=-1,head[500],cur[500];//cur用于复制head queue <int> q; void add_edge(int from,int to,int dis,bool flag) { edge[++num_edge].next=head[from]; edge[num_edge].to=to; if (flag) edge[num_edge].dis=dis;//反图的边权为 0 head[from]=num_edge; } //bfs用来分层 bool bfs(int s,int t) { memset(deep,0x7f,sizeof(deep)); while (!q.empty()) q.pop(); for (int i=1; i<=n; i++) cur[i]=head[i]; deep[s]=0; q.push(s); while (!q.empty()) { int now=q.front(); q.pop(); for (int i=head[now]; i!=-1; i=edge[i].next) { if (deep[edge[i].to]>inf && edge[i].dis)//dis在此处用来做标记 是正图还是返图 { deep[edge[i].to]=deep[now]+1; q.push(edge[i].to); } } } if (deep[t]<inf) return true; else return false; } //dfs找增加的流的量 int dfs(int now,int t,int limit)//limit为源点到这个点的路径上的最小边权 { if (!limit || now==t) return limit; int flow=0,f; for (int i=cur[now]; i!=-1; i=edge[i].next) { cur[now]=i; if (deep[edge[i].to]==deep[now]+1 && (f=dfs(edge[i].to,t,min(limit,edge[i].dis)))) { flow+=f; limit-=f; edge[i].dis-=f; edge[i^1].dis+=f; if (!limit) break; } } return flow; } void Dinic(int s,int t) { while (bfs(s,t)) maxflow+=dfs(s,t,inf); } int main() { // for (int i=0; i<=500; i++) edge[i].next=-1; memset(head,-1,sizeof(head)); scanf("%d%d",&m,&n); for (int i=1; i<=m; i++) { scanf("%d%d%d",&x,&y,&z); add_edge(x,y,z,1); add_edge(y,x,z,0); } Dinic(1,n); printf("%d",maxflow); return 0; }
(七)树图相关
#include <cstring> #include <cstdio> #include <algorithm> #include <cstdlib> #include <cmath> using namespace std; const int maxn=5e5+4; int n,m,s; int head[maxn],tot; int d[maxn],p[maxn][21]; struct ahah{ int nxt,to; }edge[maxn<<1]; void add(int u,int v) { edge[++tot].nxt=head[u];edge[tot].to=v;head[u]=tot; } void dfs(int u,int fa) { d[u]=d[fa]+1;p[u][0]=fa; for(int i=1;(1<<i)<=d[u];i++) p[u][i]=p[p[u][i-1]][i-1]; for(int i=head[u];i;i=edge[i].nxt) { int v=edge[i].to; if(v!=fa)dfs(v,u); } } int lca(int a,int b) { if(d[a]>d[b])swap(a,b); for(int i=20;i>=0;i--) if(d[a]<=d[b]-(1<<i))b=p[b][i]; if(a==b)return a; for(int i=20;i>=0;i--) { if(p[a][i]==p[b][i])continue; else a=p[a][i],b=p[b][i]; } return p[a][0]; } int main() { int x,y; scanf("%d%d%d",&n,&m,&s); for(int i=1;i<n;i++)scanf("%d%d",&x,&y),add(x,y),add(y,x); dfs(s,0); for(int i=1;i<=m;i++) { scanf("%d%d",&x,&y); printf("%d\n",lca(x,y)); } }
#include<iostream> #include <cstdio> #include <stack> using namespace std; #define N 10000 int n,m; struct ahah { int nxt,to; } edge[N]; int head[N],tot; void add(int x,int y) { edge[++tot].nxt=head[x],edge[tot].to=y; head[x]=tot; } int index,dfn[N],low[N]; stack <int> S; bool in[N]; int belong[N],cnt; void tarjan(int u) { dfn[u]=low[u]=++index; in[u]=1; S.push(u) ; for(int i=head[u]; i; i=edge[i].nxt) { int v=edge[i].to; if(!dfn[v]) { tarjan(v); if(low[v]<low[u])low[u]=low[v]; } else if(in[v]&&dfn[v]<low[u])low[u]=dfn[v]; } if(dfn[u]==low[u]) { ++cnt; int p; do { p=S.top(); S.pop() ; in[p]=0; belong[p]=cnt; } while(p!=u); } } int main() { int x,y; scanf("%d%d",&n,&m); for(int i=1; i<=m; i++)scanf("%d%d",&x,&y),add(x,y); for(int i=1; i<=n; i++)if(!dfn[i])tarjan(i); for(int i=1; i<=n; i++)printf("%d:%d ",i,belong[i]); }
#include<bits/stdc++.h> using namespace std; int m,n,k,fa[5001],xixi[2001],ans,sum; struct ahah { int nxt,to,w; } lol[200001]; bool cmp(ahah a,ahah b) { return a.w<b.w; } int find(int x) { if(fa[x]==x)return x; else return fa[x]=find(fa[x]); } int main() { scanf("%d%d",&n,&m); int x,y,z; for(int i=1; i<=n; i++)fa[i]=i; for(int i=1; i<=m; i++) { cin>>x>>y>>z; lol[i].nxt=x; lol[i].to=y; lol[i].w=z; } sort(lol,lol+1+m,cmp); for(int i=1; i<=m; i++) { int g=find(lol[i].nxt); int h=find(lol[i].to); if(g!=h) { sum+=lol[i].w; ans++; if(ans==n-1)break; fa[g]=h; } } cout<<sum; }
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; struct trie { int ch[26],f,x; }a[200005]; char T[100005],S[100005]; int n,t; queue<int>q; int main() { scanf("%d",&n); t=1; while(n--) { scanf("%s",S+1); int l=strlen(S+1),p=1; for(int i=1;i<=l;i++) { int c=S[i]-'a'; if(!a[p].ch[c])a[p].ch[c]=++t; p=a[p].ch[c]; } ++a[p].x; } for(int i=0;i<26;i++) { if(a[1].ch[i]) { a[a[1].ch[i]].f=1; q.push(a[1].ch[i]); }else a[1].ch[i]=1; } while(!q.empty()) { int u=q.front();q.pop(); for(int i=0;i<26;i++) if(a[u].ch[i]) { a[a[u].ch[i]].f=a[a[u].f].ch[i]; q.push(a[u].ch[i]); }else a[u].ch[i]=a[a[u].f].ch[i]; } return 0; }
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <vector> #include <cmath> #include <queue> #define LL long long using namespace std; const int maxn=1e5+2; typedef pair<int,int> pii; priority_queue<pii,vector<pii>,greater<pii> > Q; struct ahah{ int nxt,to,dis; }edge[maxn*2]; int head[maxn],tot; int d[maxn]; bool vis[maxn]; void add(int x,int y,int z) { edge[++tot].nxt=head[x];edge[tot].to=y;edge[tot].dis=z;head[x]=tot; } int n,m,s; void dijkstra(int s) { for(int i=1;i<=n;i++)d[i]=1234567890; Q.push(make_pair(0,s)); d[s]=0; while(!Q.empty()) { while(!Q.empty()&&vis[Q.top().second])Q.pop(); if(Q.empty())return; int temp=Q.top().second; d[temp]=Q.top().first; vis[temp]=1; Q.pop(); for(int i=head[temp];i;i=edge[i].nxt) { if(!vis[edge[i].to])Q.push(make_pair(d[temp]+edge[i].dis,edge[i].to)); } } } int main() { cin>>n>>m>>s; int x,y,z; for(int i=1;i<=m;i++) { cin>>x>>y>>z; add(x,y,z); // add(y,x,z); } dijkstra(s); for(int i=1;i<=n;i++)cout<<d[i]<<" "; }
二·数据结构部分
(一)并查集
#include<bits/stdc++.h> using namespace std; int m,n,fa[200001]; int find(int x) { if(fa[x]==x)return x; else return fa[x]=find(fa[x]); } int main() { cin>>m>>n; for(int i=1; i<=m; i++)fa[i]=i; int x,y,z; for(int i=1; i<=n; i++) { scanf("%d%d%d",&x,&y,&z); if(x==1) { int g=find(y); int h=find(z); if(g!=h)fa[g]=h; } if(x==2) { int g=find(y); int h=find(z); if(g==h)cout<<"Y\n"; else cout<<"N\n"; } } }
(二)堆STL
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <vector> #include <queue> #define mian main #define N int(1e6+2) using namespace std; priority_queue <int,vector<int>,greater<int> >heap; int n,a[N],now; int f,k; int main() { scanf("%d",&n); while(n--) { scanf("%d",&f); if(f==1) { scanf("%d",&k); heap.push(k); } else if(f==2)printf("%d\n",heap.top()); else heap.pop() ; } }
(三)线段树
#include<cstdio> #include<iostream> using namespace std; long long n,m,ans,x,y,ch,val; struct ahah{ long long l,r,sum,f; }tree[200000<<2]; void build(int k,int l,int r) { tree[k].l=l;tree[k].r=r; if(tree[k].l==tree[k].r) { scanf("%lld",&tree[k].sum); return ; } long long mid=(tree[k].l+tree[k].r)>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum; } void update(int k) { if(tree[k].l==tree[k].r) { tree[k].sum+=y; return ; } long long mid=(tree[k].l+tree[k].r)>>1; if(x<=mid)update(k<<1); else update(k<<1|1); tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum; } void down(long long k) { tree[k<<1].f+=tree[k].f; tree[k<<1|1].f+=tree[k].f; tree[k<<1].sum+=(tree[k<<1].r-tree[k<<1].l+1)*tree[k].f; tree[k<<1|1].sum+=(tree[k<<1|1].r-tree[k<<1|1].l+1)*tree[k].f; tree[k].f=0; } void query(int k) { if(x<=tree[k].l&&y>=tree[k].r) { ans+=tree[k].sum; return ; } if(tree[k].f)down(k); long long mid=(tree[k].l+tree[k].r)>>1; if(x<=mid)query(k<<1); if(y>mid)query(k<<1|1); } void add(long long k) { if(tree[k].l>=x&&tree[k].r<=y) { tree[k].sum+=(tree[k].r-tree[k].l+1)*val; tree[k].f+=val; return ; } if(tree[k].f) down(k); long long mid=(tree[k].l+tree[k].r)>>1; if(x<=mid)add(k<<1); if(y>mid)add(k<<1|1); tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum; } int main() { scanf("%lld%lld",&n,&m); build(1,1,n); for(int i=1;i<=m;i++) { ans=0; cin>>ch>>x>>y; if(ch==1) { cin>>val; add(1); } else { query(1); cout<<ans<<"\n"; } } }
(四)2B平衡树
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; struct tree { int lc,rc,rt; }a[100005]; int b[50005],cnt,t,n,m,q,x,y,z,ac; int ch[2000005][2],f[2000005],w[2000005],sum[2000005]; inline int getwh(int u){return ch[f[u]][0]==u?0:1;} inline void rotate(int u) { int fa=f[u],gr=f[fa],wh=getwh(u); f[u]=gr; ch[gr][getwh(fa)]=u; f[ch[u][wh^1]]=fa; ch[fa][wh]=ch[u][wh^1]; f[fa]=u; ch[u][wh^1]=fa; sum[fa]=sum[ch[fa][0]]+sum[ch[fa][1]]+1; sum[u]=sum[ch[u][0]]+sum[ch[u][1]]+1; } inline void splay(int &root,int u) { while(f[u]) { if(f[f[u]]) { if(getwh(u)==getwh(f[u]))rotate(f[u]); else rotate(u); } rotate(u); } root=u; f[u]=0; } inline void ins(int &root,int x) { int last,now=root; while(now) { last=now; ++sum[last]; if(x<=w[now])now=ch[now][0]; else now=ch[now][1]; } ch[last][x<=w[last]?0:1]=++t; f[t]=last; w[t]=x; sum[t]=1; ch[t][0]=ch[t][1]=0; splay(root,t); } inline int find(int &root,int x) { int now=root; while(w[now]!=x) { if(x<w[now])now=ch[now][0]; else now=ch[now][1]; } return now; } inline void del(int &root,int x) { splay(root,find(root,x)); if(ch[root][0]==0) { root=ch[root][1]; f[root]=0; return; } if(ch[root][1]==0) { root=ch[root][0]; f[root]=0; return; } int l=ch[root][0],r=ch[root][1],last; root=ch[root][1]; f[root]=0; while(ch[r][0])sum[r]+=sum[l],r=ch[r][0]; sum[r]+=sum[l]; ch[r][0]=l; f[l]=r; } inline int getrank(int &root,int x) { int ac=0,now=root; while(now) { if(x>w[now]) { ac+=sum[ch[now][0]]+1; now=ch[now][1]; }else now=ch[now][0]; } return ac; } inline int getpre(int &root,int x) { int ac=-1,now=root; while(now) { if(w[now]<x) { ac=w[now]; now=ch[now][1]; }else now=ch[now][0]; } return ac; } inline int getnxt(int &root,int x) { int ac=1e8+1,now=root; while(now) { if(w[now]>x) { ac=w[now]; now=ch[now][0]; }else now=ch[now][1]; } return ac; } void build(int u,int l,int r) { a[u].rt=++t; ch[t][0]=ch[t][1]=f[t]=0; w[t]=b[l]; sum[t]=1; for(int i=l+1;i<=r;i++)ins(a[u].rt,b[i]); if(l==r)return; int mid=(l+r)>>1; a[u].lc=++cnt; build(cnt,l,mid); a[u].rc=++cnt; build(cnt,mid+1,r); } void segrank(int u,int l,int r,int ll,int rr,int w) { if(l==ll&&r==rr) { ac+=getrank(a[u].rt,w); return; } int mid=(l+r)>>1; if(rr<=mid)segrank(a[u].lc,l,mid,ll,rr,w); else if(ll>mid)segrank(a[u].rc,mid+1,r,ll,rr,w); else { segrank(a[u].lc,l,mid,ll,mid,w); segrank(a[u].rc,mid+1,r,mid+1,rr,w); } } inline int rankinlr(int w,int l,int r) { ac=0; segrank(1,1,n,l,r,w); return ac+1; } void updata(int u,int l,int r,int x,int ww) { if(l==r) { a[u].rt=++t; ch[t][0]=ch[t][1]=f[t]=0; w[t]=ww; sum[t]=1; return; } del(a[u].rt,b[x]); ins(a[u].rt,ww); int mid=(l+r)>>1; if(x<=mid)updata(a[u].lc,l,mid,x,ww); else updata(a[u].rc,mid+1,r,x,ww); } void segpre(int u,int l,int r,int ll,int rr,int w) { if(l==ll&&r==rr) { ac=max(ac,getpre(a[u].rt,w)); return; } int mid=(l+r)>>1; if(rr<=mid)segpre(a[u].lc,l,mid,ll,rr,w); else if(ll>mid)segpre(a[u].rc,mid+1,r,ll,rr,w); else { segpre(a[u].lc,l,mid,ll,mid,w); segpre(a[u].rc,mid+1,r,mid+1,rr,w); } } void segnxt(int u,int l,int r,int ll,int rr,int w) { if(l==ll&&r==rr) { ac=min(ac,getnxt(a[u].rt,w)); return; } int mid=(l+r)>>1; if(rr<=mid)segnxt(a[u].lc,l,mid,ll,rr,w); else if(ll>mid)segnxt(a[u].rc,mid+1,r,ll,rr,w); else { segnxt(a[u].lc,l,mid,ll,mid,w); segnxt(a[u].rc,mid+1,r,mid+1,rr,w); } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&b[i]); cnt=1; t=0; build(1,1,n); while(m--) { scanf("%d%d%d",&q,&x,&y); if(q!=3)scanf("%d",&z); if(q==1)printf("%d\n",rankinlr(z,x,y)); if(q==2) { int l=0,r=1e8+1; while(r-l>1) { int mid=(l+r)>>1; if(rankinlr(mid,x,y)<=z)l=mid;else r=mid; } printf("%d\n",l); } if(q==3) { updata(1,1,n,x,y); b[x]=y; } if(q==4) { ac=-1; segpre(1,1,n,x,y,z); printf("%d\n",ac); } if(q==5) { ac=1e8+1; segnxt(1,1,n,x,y,z); printf("%d\n",ac); } } return 0; }
(五)splay
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,a[100005]; struct Splay { int rt,f[100005],ch[100005][2],sum[100005],t; int build(int l,int r) { int mid=(l+r)>>1; sum[mid]=r-l+1; ch[mid][0]=l<mid?build(l,mid-1):0; ch[mid][1]=mid<r?build(mid+1,r):0; f[ch[mid][0]]=f[ch[mid][1]]=mid; return mid; } inline int getwh(int u){return ch[f[u]][0]==u?0:1;} inline void rotate(int u) { int fa=f[u],gr=f[fa],wh=getwh(u); f[u]=gr; ch[gr][getwh(fa)]=u; f[ch[u][wh^1]]=fa; ch[fa][wh]=ch[u][wh^1]; f[fa]=u; ch[u][wh^1]=fa; sum[fa]=sum[ch[fa][0]]+sum[ch[fa][1]]+1; sum[u]=sum[ch[u][0]]+sum[ch[u][1]]+1; } inline void splay(int u,int tar) { while(f[u]!=tar) { if(f[f[u]]!=tar) { if(getwh(u)==getwh(f[u]))rotate(f[u]); else rotate(u); } rotate(u); } if(!tar)rt=u; } int findkth(int key) { int o=rt; while(1) { if(sum[ch[o][0]]+1==key)return o; if(key<=sum[ch[o][0]])o=ch[o][0]; else { key-=sum[ch[o][0]]+1; o=ch[o][1]; } } } int getrank(int key) { int o=rt,ac=0; while(o) { if(a[o]<key) { ac+=sum[ch[o][0]]+1; o=ch[o][1]; }else o=ch[o][0]; } return ac+1; } void merge(int x,int y) { if(x==0){rt=y;return;} if(y==0){rt=x;return;} while(ch[y][0]) { sum[y]+=sum[x]; y=ch[y][0]; } sum[y]+=sum[x]; ch[y][0]=x,f[x]=y; splay(x,0); } void ins(int w) { a[++t]=w,sum[t]=1; if(rt==0) { rt=t; return; } int o=rt,last; while(o) { ++sum[last=o]; if(w<a[o])o=ch[o][0]; else o=ch[o][1]; } f[t]=last,ch[last][w<a[last]?0:1]=t; splay(t,0); } void del(int u) { splay(u,0); f[ch[u][0]]=f[ch[u][1]]=0; merge(ch[u][0],ch[u][1]); } }splay; int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); splay.rt=splay.build(1,n); splay.t=n; return 0; }
数学数论部分
(一)筛素数
memset(check, 0, sizeof(check)); int tot = 0; for (int i = 2; i <= n; ++i) { if (!check[i]) { prime[tot++] = i; } for (int j = i+i; j <= n; j += i) { check[j] = 1; } }
#include <iostream> #include <cstdio> #include <queue> using namespace std; #define N int(1e7+2) #define M int(5e5+2) #define L 2147483647 int n,m; bool prime[N]; int f[N],tot; int read() { int sum=0,fg=1; char c=getchar(); while(c<'0'||c>'9'){if(c=='-')fg=-1;c=getchar();} while(c>='0'&&c<='9'){sum=sum*10+c-'0';c=getchar();} return sum*fg; } void _prime() { for(int i=1;i<=n;i++)prime[i]=1; prime[1]=0; for(int i=2;i<=n/2;i++) { if(prime[i])f[++tot]=i; for(int j=1;j<=tot&&f[j]*i<=n;j++) { prime[f[j]*i]=0; if(i%f[j]==0)break; } } } int main() { int x; n=read(),m=read(); _prime(); while(m--) { x=read(); if(prime[x])printf("Yes\n"); else printf("No\n"); } }
(二)组合数递推
for(int i=1; i<=2001; i++) { f[i][0]=1,f[i][i]=1; for(int j=1; j<i; j++)f[i][j]=(f[i-1][j-1]+f[i-1][j])%k; }
(三)最小公约数与最大公倍数
#include <iostream> using namespace std; int main() { int m,n,r,t; cout<<"请输入两个值,求最小公倍数"<<endl; cin>>m>>n; int a = m; //先把m、n保存一份 int b = n; if(m<n) { t=m; //用分号 m=n; //用分号 n=t; } while((r=m%n)!=0) { m=n; n=r; } cout<<"最大公约数="<< n << endl; cout<<"最小公倍数="<< a * b / n << endl; //最后这样打印 }
(四)欧几里得扩展
#include <cstdio> int exgcd(int a, int b, int &x, int &y) //非递归版 { int d; if (!b) x = 1, y = 0, d = a; else { d = exgcd(b, a % b, y, x); y -= (a / b) * x; } return d; } int exgcd(int a, int b, int &x, int &y) //递归版 { int d; return !b ? (x = 1, y = 0, a) : (d = exgcd(b, a % b, y, x), y -= (a / b) * x, d); } int main() { int a, b, x, y; scanf ("%d%d", &a, &b); printf("%d\n", exgcd(a, b, x, y)); printf("%d %d\n", x, y); }
(五)高斯消元
#include <iostream> #include <cstdio> #include <cmath> using namespace std; const double eps=1e-8; int n; double a[111][111]; double b[111]; double ans[111]; int sign(double x) { if(fabs(x)<=eps)return 0; if(x>0)return 1; return -1; } int main() { // printf("%lf",eps); scanf("%d",&n); for(int i=1;i<=n;i++) { for(int j=1;j<=n+1;j++)scanf("%lf",&a[i][j]); } // cout<<n<<"\n"; for(int i=1;i<=n;i++) { if(fabs(a[i][i])<=eps) { printf("No Solution\n"); return 0; } int p=i; for(int j=i;j<=n;j++) { if(fabs(a[j][i])>fabs(a[p][i]))p=j; } for(int j=1;j<=n+1;j++)swap(a[i][j],a[p][j]); // swap(b[i],b[p]); for(int j=i+1;j<=n;j++) { double ratio=a[j][i]/a[i][i]; for(int k=1;k<=n+1;k++)a[j][k]=a[j][k]-a[i][k]*ratio; } // for(int j=1;j<=n;j++)printf("%lfX1+%lfX2+%lfX3=%lf\n",a[j][1],a[j][2],a[j][3],a[j][4]);cout<<"\n"; } for(int i=n;i>=1;i--) { for(int j=n;j>i;j--) { if(sign(a[i][j])==0)break; a[i][n+1]-=ans[j]*a[i][j]; } ans[i]=a[i][n+1]/a[i][i]; } for(int i=1;i<=n;i++)printf("%.2lf\n",ans[i]); }
(六)卢卡斯定理
#include <cstdio> #include <cctype> typedef long long LL; #define dd c=getchar() inline void read(LL &x) { x=0; char dd; bool f=false; for(; !isdigit(c); dd)if(c=='-')f=true; for(; isdigit(c); dd) x=(x<<1)+(x<<3)+(c^48); if(f)x=-x; return; } typedef long long LL; LL mod; inline LL pow(LL a,LL b)//快速幂是为了求逆元 { LL ans=1; for(; b; b>>=1,a=a*a%mod)if(b&1)ans=ans*a%mod; return ans; } LL farc[1000005]; inline void prepare(LL a) { farc[0]=1; for(LL i=1; i<=a; ++i)farc[i]=farc[i-1]*i%mod; } inline LL Csmall(LL m,LL n)//C(m,n)=(n!)/(m!*(n-m)!) { if(n<m)return 0; return farc[n]*pow(farc[m],mod-2)%mod*pow(farc[n-m],mod-2)%mod;//费马小定理求逆元 } /*递归形式 inline LL C(LL m,LL n) { if(n<m) return 0; if(!n) return 1;//Lucas的边界条件 return C(m/mod,n/mod)%mod*Csmall(m%mod,n%mod)%mod;//上面证明的Lucas定理 } */ inline LL C(LL m,LL n) { LL ans=1; while(n&&m&&ans) { ans=(ans*Csmall(m%mod,n%mod))%mod; n/=mod,m/=mod; } return ans; } int main() { LL T; read(T); while(T--) { LL m,n; read(m); read(n); read(mod); prepare(m+n); printf("%lld\n",C(n,m+n)); } return 0; }
目前整理就这么多了,以后会持续更新
除特别注明外,本站所有文章均为Manjusaka丶梦寒原创,转载请注明来自出处