NOIP模板整理
来源:互联网 发布:ubuntu安装qt5 编辑:程序博客网 时间:2024/05/01 19:02
2016NOIP RP++
持续更新中……
图论:
1.最短路:
floyd
#include<iostream>#include<cstdio>#include<cstdlib>using namespace std;const int maxn=1005;int d[maxn][maxn];int n,m,s,e;void floyd(){ for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(i!=j&&i!=k&&k!=j) d[i][j]=min(d[i][j],d[i][k]+d[k][j]); }int main(){ scanf("%d%d%d%d",&n,&m,&s,&e); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) d[i][j]=1e9; for(int i=1;i<=m;i++) { int f,t,c; scanf("%d%d%d",&f,&t,&c); d[f][t]=c; d[t][f]=c; } floyd(); printf("%d\n",d[s][e]); return 0; }
Ⅱspfa
①普通:
#include<iostream>#include<cstdio>#include<cstdlib>#include<queue>using namespace std;const int maxn=100005;struct dqs{ int f,t,c;}hh[maxn];int tot=0,first[maxn],next[maxn],d[maxn];bool used[maxn];void build(int f,int t,int c){ hh[++tot]=(dqs){f,t,c}; next[tot]=first[f]; first[f]=tot;}queue<int>q;int n,m,s,e;void spfa(int s){ d[s]=0; q.push(s); used[s]=1; while(!q.empty()) { int x=q.front(); q.pop(); used[x]=0; for(int i=first[x];i;i=next[i]) { int u=hh[i].t; if(d[u]>d[x]+hh[i].c) { d[u]=d[x]+hh[i].c; if(!used[u]) { q.push(u); used[u]=1; } } } }}int main(){ scanf("%d%d%d%d",&n,&m,&s,&e); for(int i=1;i<=n;i++) d[i]=1e9; for(int i=1;i<=m;i++) { int f,t,c; scanf("%d%d%d",&f,&t,&c); build(f,t,c); build(t,f,c); } spfa(s); printf("%d\n",d[e]); return 0;}
②spfa(slf优化)
deque<int>q;void spfa(int s){ for(int i=1;i<=n;i++) d[i]=1e9; d[s]=0; q.push_back(s); used[s]=1; while(!q.empty()) { int x=q.front(); q.pop_front(); used[x]=0; for(int i=first[x];i;i=next[i]) { int u=hh[i].t; if(d[u]>d[x]+hh[i].c) { d[u]=d[x]+hh[i].c; if(!used[u]) { used[u]=1; if(!q.empty()) { if(d[u]<d[q.front()]) q.push_front(u); else q.push_back(u); } else q.push_back(u); } } } }}
③spfa判负环
int tim[maxn];bool spfa(int s){ d[s]=0; q.push(s); used[s]=1; while(!q.empty()) { int x=q.front(); q.pop(); used[x]=0; for(int i=first[x];i;i=next[i]) { int u=hh[i].t; if(d[u]>d[x]+hh[i].c) { d[u]=d[x]+hh[i].c; if(!used[u]) { if(++tim[u]>n) return false; q.push(u); used[u]=1; } } } } return true;}
ⅢDijkstra算法
①普通
#include<iostream>#include<cstdio>#include<cstdlib>using namespace std;const int maxn=100005;struct dqs{ int f,t,c;}hh[maxn];int tot=0,first[maxn],next[maxn],d[maxn];bool used[maxn];void build(int f,int t,int c){ hh[++tot]=(dqs){f,t,c}; next[tot]=first[f]; first[f]=tot;}int n,m,s,e;void Dijkstra(){ for(int i=1;i<=n;i++) d[i]=1e9; d[s]=0; while(true) { int x=-1; for(int i=1;i<=n;i++) { if(!used[i]) if(x==-1||d[i]<d[x]) x=i; if(x==-1) break; used[x]=1; for(int i=first[x];i;i=next[i]) { int u=hh[i].t; if(d[u]>d[x]+hh[i].c) d[u]=d[x]+hh[i].c; } } }}int main(){ scanf("%d%d%d%d",&n,&m,&s,&e); ......}
②堆优化
#include<iostream>#include<cstdio>#include<cstdlib>#include<queue>using namespace std;const int maxn=200005;struct dqs{ int f,t,c;}hh[maxn];struct dqm{ int num,dis;};bool operator <(dqm a,dqm b){ return a.dis>b.dis;}int tot=0,first[maxn],next[maxn],d[maxn];bool used[maxn];void build(int f,int t,int c){ hh[++tot]=(dqs){f,t,c}; next[tot]=first[f]; first[f]=tot;}priority_queue<dqm>q;void dij(int s){ d[s]=0; q.push({s,d[s]}); while(!q.empty()) { int head = q.top().num; q.pop(); used[head]=1; for(int i=first[head];i;i=next[i]) { int u=hh[i].t; if(d[u]>d[head]+hh[i].c) { d[u]=d[head]+hh[i].c; if(!used[u]) q.push((dqm){u,d[u]}); } } }}int main(){ int n,m,s,e; scanf("%d%d%d%d",&n,&m,&s,&e); ......}
2.最小生成树
①kruskal:
#include<iostream>#include<cstdio>#include<cstdlib>#include<algorithm>using namespace std;const int maxn=200005;struct dqs{ int f,t,c;}hh[maxn];int fa[maxn];bool cmp(dqs a,dqs b){ return a.c<b.c;}int find(int x){ if(fa[x]==x) return x; else return fa[x]=find(fa[x]);}int main(){ int n,m,tot=0,ans=0; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) fa[i]=i; for(int i=1;i<=m;i++) { int f,t,c; scanf("%d%d%d",&f,&t,&c); hh[++tot]=(dqs){f,t,c}; } sort(hh+1,hh+tot+1,cmp); for(int i=1;i<=tot;i++) { int x=find(hh[i].f); int y=find(hh[i].t); if(x!=y) { fa[x]=y; ans+=hh[i].c; } } printf("%d\n",ans); return 0;}
3. LCA
模板:小机房的树
①暴力
#include<iostream>#include<cstdio>#include<cstdlib>using namespace std;const int maxn=100005;struct dqs{ int f,t,c;}hh[maxn];int deep[maxn],d[maxn],fa[maxn]; int tot=0,first[maxn],next[maxn];void build(int f,int t,int c){ hh[++tot]=(dqs){f,t,c}; next[tot]=first[f]; first[f]=tot;}void dfs(int x,int sd){ deep[x]=sd; for(int i=first[x];i;i=next[i]) { int u=hh[i].t; if(deep[u]) continue; else { fa[u]=x; d[u]=d[x]+hh[i].c; dfs(u,sd+1); } }}int lca(int x,int y){ if(deep[x]<deep[y]) swap(x,y); while(deep[x]>deep[y]) { x=fa[x]; } while(x!=y) { x=fa[x]; y=fa[y]; } return x;}int main(){ int n; scanf("%d",&n); for(int i=1;i<=n-1;i++) { int f,t,c; scanf("%d%d%d",&f,&t,&c); build(f,t,c); build(t,f,c); } dfs(1,0); int m; scanf("%d",&m); for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); int xx=lca(u,v); printf("%d\n",d[u]+d[v]-2*d[xx]); }}
②倍增
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int maxn=250010;struct dqs{ int f,t,c;}hh[maxn<<1];int tot=0,fa[maxn][31],next[maxn],first[maxn],f[maxn],d[maxn];void build(int ff,int tt,int cc){ hh[++tot]=(dqs){ff,tt,cc}; next[tot]=first[ff]; first[ff]=tot;}int deep[maxn];void dfs(int x,int sd){ deep[x]=sd; int u; for(int i=first[x];i;i=next[i]) { u=hh[i].t; if(!deep[u]&&u) { f[u]=x; d[u]=d[x]+hh[i].c; dfs(u,sd+1); } }}int lca(int x,int y){ if(deep[x]<deep[y]) swap(x,y); int deepcha=deep[x]-deep[y]; for(int i=0;i<=30;i++) { if(1<<i&deepcha) x=fa[x][i]; } for(int i=30;i>=0;i--) { if(fa[x][i]!=fa[y][i]) { x=fa[x][i]; y=fa[y][i]; } } if(x!=y) return f[x]; return x;}int main(){ int n; scanf("%d",&n); int u,v,c; for(int i=1;i<n;i++) { scanf("%d%d%d",&u,&v,&c); build(u,v,c); build(v,u,c); } dfs(0,0); for(int i=0;i<n;i++) fa[i][0]=f[i]; for(int j=1;j<=20;j++) for(int i=1;i<=n;i++) fa[i][j]=fa[fa[i][j-1]][j-1]; int m; scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%d%d",&u,&v); int xx=lca(u,v); printf("%d\n",d[u]+d[v]-2*d[xx]); } return 0;}
4. 拓扑排序
模板:poj2367
#include<iostream>#include<cstdio>#include<cstdlib>#include<queue>using namespace std;const int maxn=200005;struct dqs{ int f,t,c;}hh[maxn];int tot=0,first[maxn],next[maxn],du[maxn];void build(int f,int t){ hh[++tot]=(dqs){f,t}; next[tot]=first[f]; first[f]=tot;}queue<int>q;void tp(){ while(!q.empty()) { int x=q.front(); q.pop(); printf("%d ",x); for(int i=first[x];i;i=next[i]) { int u=hh[i].t; du[u]--; if(!du[u]) q.push(u); } }}int main(){ int n; scanf("%d",&n); for(int i=1;i<=n;i++) { int x; while(true) { scanf("%d",&x); if(x==0) break; build(i,x); du[x]++; } } for(int i=1;i<=n;i++) if(!du[i]) q.push(i); tp(); return 0;}
5. Tarjan(无向图求环)
强连通分量:
模板:codevs2822爱在心中
#include<iostream>#include<cstdio>#include<cstdlib>using namespace std;const int maxn=10005;struct dqs{ int f,t;}hh[maxn];int tot=0;int first[maxn],next[maxn];void build(int f,int t){ hh[++tot]=(dqs){f,t}; next[tot]=first[f]; first[f]=tot;}int dfn[maxn],low[maxn],stack[maxn],size[maxn],du[maxn],jlqlt[maxn];bool in_stack[maxn];int tot1=0,cnt=0,snum=0;void group(int x){ dfn[x]=low[x]=++tot1; stack[++snum]=x; in_stack[x]=1; for(int i=first[x];i;i=next[i]) { int u=hh[i].t; if(!dfn[u]) { group(u); low[x]=min(low[x],low[u]); } else if(in_stack[u]) low[x]=min(low[x],dfn[u]); } if(dfn[x]==low[x]) { cnt++; while(true) { jlqlt[stack[snum]]=cnt; in_stack[stack[snum]]=0; size[cnt]++; snum--; if(stack[snum+1]==x) break; } }}int main(){ int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int a,b; scanf("%d%d",&a,&b); build(a,b); } for(int i=1;i<=n;i++) if(!dfn[i]) group(i); for(int i=1;i<=n;i++) for(int j=first[i];j;j=next[j]) { int u=hh[j].t; if(jlqlt[i]!=jlqlt[u]) du[jlqlt[i]]++; } int sum1=0,sum2=0,x; for(int i=1;i<=cnt;i++) { if(size[i]>1) sum1++; if(!du[i]) { sum2++; x=i; } } printf("%d\n",sum1); if(sum2==1&&size[x]!=1) { for(int i=1;i<=n;i++) { if(jlqlt[i]==x) printf("%d ",i); } } else printf("-1\n"); return 0;}
数据结构
1.线段树
模板:区间修改,区间查询
#include<iostream>#include<cstdio>#include<cstdlib>using namespace std;typedef long long ll;const int maxn=200005;struct dqs{ int l,r; ll add; ll sum;}hh[maxn<<2];int xl[maxn];void build(int p,int l,int r){ hh[p].l=l; hh[p].r=r; if(l==r) { hh[p].sum=xl[l]; return; } int mid=(l+r)>>1; build(p*2,l,mid); build(p*2+1,mid+1,r); hh[p].sum=hh[p*2].sum+hh[p*2+1].sum;}void spread(int p){ if(hh[p].add) { hh[p*2].sum+=(ll)(hh[p*2].r-hh[p*2].l+1)*(ll)hh[p].add; hh[p*2+1].sum+=(ll)(hh[p*2+1].r-hh[p*2+1].l+1)*(ll)hh[p].add; hh[p*2].add+=hh[p].add; hh[p*2+1].add+=hh[p].add; hh[p].add=0; }}void change(int p,int l,int r,ll x){ if(hh[p].l>=l&&hh[p].r<=r) { hh[p].sum+=(long long)(hh[p].r-hh[p].l+1)*x; hh[p].add+=x; return; } spread(p); int mid=(hh[p].l+hh[p].r)>>1; if(l<=mid) change(p*2,l,r,x); if(mid<r) change(p*2+1,l,r,x); hh[p].sum = hh[p*2].sum+hh[p*2+1].sum;}ll ask(int p,int l,int r){ if(l<=hh[p].l&&hh[p].r<=r) return hh[p].sum; spread(p); ll ans = 0; int mid=(hh[p].l+hh[p].r)>>1; if(l<=mid) ans += ask(p*2,l,r); if(mid<r) ans += ask(p*2+1,l,r); return ans;}int main(){ int n,q; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&xl[i]); build(1,1,n); scanf("%d",&q); for(int i=1;i<=q;i++) { int read; scanf("%d",&read); if(read==1) { int a,b; ll c; scanf("%d%d%lld",&a,&b,&c); change(1,a,b,c); } if(read==2) { int a,b; scanf("%d%d",&a,&b); printf("%lld\n",ask(1,a,b)); } } return 0;}
2.排序
Ⅰ归并排序
#include<iostream>#include<cstdio>#include<cstdlib>using namespace std;const int maxn=200005; long long tmp[maxn],a[maxn];long long ans=0;void merge(int l,int mid,int r){ int i=l,j=mid+1,k=l; while(i<=mid&&j<=r) { if(a[i]>a[j]) { tmp[k++]=a[j++]; ans+=mid+1-i; } else tmp[k++]=a[i++]; } while(i<=mid) tmp[k++]=a[i++]; while(j<=r) tmp[k++]=a[j++]; for(int i=l;i<=r;i++) a[i]=tmp[i];}void merge_sort(int l,int r){ if(l<r) { int mid=(l+r)>>1; merge_sort(l,mid); merge_sort(mid+1,r); merge(l,mid,r); } }int main(){ int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); merge_sort(1,n); for(int i=1;i<=n;i++) cout<<a[i]<<" "; cout<<endl; printf("%lld",ans);}
Ⅱ堆排序(小根)
①手打堆排序
#include<iostream>#include<cstdio>#include<cstdlib>using namespace std;const int maxn=200005;int heap[maxn],cnt=0;void push(int x){ cnt++; int now=cnt; heap[now]=x; while(now>1) { if(heap[now]<heap[now/2]) { swap(heap[now],heap[now/2]); now/=2; } else break; }}void pop(){ heap[1]=heap[cnt]; int now=1; while(now*2+1<=cnt) { int l=now*2,r=now*2+1; if(heap[l]<heap[now]) { if(heap[r]<heap[l]) swap(l,r); swap(heap[l],heap[now]); now=l; } else if(heap[r]<heap[now]) { swap(heap[r],heap[now]); now=r; } else break; } cnt--;}int main(){ int n; scanf("%d",&n); for(int i=1;i<=n;i++) { int x; scanf("%d",&x); push(x); } for(int i=1;i<=n;i++) { printf("%d ",heap[1]); pop(); }}
②STL实现
#include<iostream>#include<cstdio>#include<cstdlib>#include<queue>using namespace std;const int maxn=200005;struct dqs{ int num;};bool operator<(dqs a,dqs b){ return a.num>b.num;}priority_queue<dqs>q;int main(){ int n; dqs x; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&x.num); q.push(x); } while(!q.empty()) { printf("%d ",q.top()); q.pop(); } return 0;}
数论
1.筛法
Ⅰ线性筛
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring> using namespace std;const int maxn=200005;int prime[maxn];bool not_prime[maxn];int main(){ int n,cnt=0; scanf("%d",&n); memset(not_prime,0,sizeof(not_prime)); not_prime[1]=true; for(int i=2;i<=n;i++) { if(!not_prime[i]) prime[++cnt]=i; for(int j=1;j<=cnt;j++) { if(prime[j]*i>n) break; not_prime[prime[j]*i]=true; if(i%prime[j]==0) break; } } for(int i=1;i<=cnt;i++) printf("%d ",prime[i]); return 0;}
Ⅱ埃式筛
2.拓展欧几里得算法
#include<iostream>#include<cstdio>#include<cstdlib>#include<algorithm>using namespace std;int x,y;int exgcd(int a,int b){ if(!b) { x=1; y=0; return a; } else { int t; int d=exgcd(b,a%b); t=x; x=y; y=t-a/b*x; return d; }}int main(){ int a,b; scanf("%d%d",&a,&b); exgcd(a,b);// cout<<__gcd(a,b)<<endl; cout<<x<<" "<<y<<endl; return 0;}
3.gcd+lcm
#include<iostream>#include<cstdio>#include<cstdlib>using namespace std;int gcd(int a,int b){ if(!b) return a; else return gcd(b,a%b);}int lcm(int a,int b){ return a/gcd(a,b)*b;}int main(){ int a,b; scanf("%d%d",&a,&b); cout<<gcd(a,b)<<" "<<lcm(a,b)<<endl; return 0;}
4.分解质因数
#include<iostream>#include<cstdio>#include<cstdlib>using namespace std;int main(){ long long n; scanf("%lld",&n); for(long long i=2;i<=n;i++) { while(n!=i) { if(n%i==0) { printf("%lld*",i); n=n/i; } else break; } } printf("%lld",n); return 0;}
5.大数翻倍法
#include<iostream>#include<cstdio>#include<cstdlib>using namespace std;int a[233],mo[233];int gcd(int a,int b){ if(!b) return a; else return gcd(b,a%b);} int lcm(int a,int b){ return a/gcd(a,b)*b;}int main(){ int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&mo[i]); int ans=0,nowmo=1; for(int i=1;i<=n;i++) { int other=a[i],othermo=mo[i]; if(othermo>nowmo) { swap(ans,other); swap(nowmo,othermo); } while(ans%othermo!=other) ans+=nowmo; nowmo=lcm(nowmo,othermo); } printf("%d",ans);}
4 0
- NOIP 考前模板整理
- noip模板整理
- NOIP模板整理
- NOIP 模板整理
- NOIP 前夕 模板整理
- NOIP前夕模板整理第一弹:图论
- NOIP前夕模板整理第二弹:数据结构
- NOIP知识汇总及模板整理
- 16年NOIP复赛前各种模板的整理
- NOIP 模板整理计划 NOIP2017 RP++(持续更新中~)
- NOIP模板
- NOIP 模板整理(多图预警╮(╯▽╰)╭)
- NOIP历年搜索整理
- NOIP模板大全
- 【NOIP模板】 tarjan
- 【NOIP模板】KMP
- 【NOIP模板】 树状数组
- 【NOIP模板】 线段树
- 【Studio】解决格式化时,注释部分没有缩进的问题
- 抽象类
- 找出php中可能有问题的代码行
- Jacobian矩阵、Hessian矩阵、特征值、特征向量
- 赠券收集者问题
- NOIP模板整理
- java excle导入 导出
- UCRT: VC 2015 Universal CRT, by Microsoft
- LoadDriverRegistry
- [操作系统]自动化集成部署udeployer 批量统一安装一键部署
- Volley中json请求POST
- mysql cmd 窗口乱码
- 欢迎使用CSDN-markdown编辑器
- 牛人(周志华)推荐的人工智能网站