noip复习模板
Posted 123456
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了noip复习模板相关的知识,希望对你有一定的参考价值。
我只会这么多
tarjan:codevs 1332
void tarjan(int u) { dfn[u]=low[u]=Time++; s.push(u); for(int i=head[u];~i;i=nxt[i]) { int v=to[i]; if(!dfn[v]) tarjan(v); else if(dfn[v]!=-1) low[u]=Min(low[u],low[v]); } if(dfn[u]==dfn[v]) { while(!s.empty()) { int x=s.top(); s.pop(); dfn[x]=-1; tot++; if(x==u) break; } } }
spfa codevs 2038
#include<iostream> #include<queue> #include<stdio.h> #include<string.h> using namespace std; const int inf=0x3f3f3f3f; int cnt=-1,n,e,s,t,ans=inf,p; int head[500010],to[500010],w[500010],nxt[500010],d[500010],used[500010],pos[500010]; int Min(int x,int y) { return x<y?x:y; } void Init() { memset(head,-1,sizeof(head)); memset(nxt,-1,sizeof(nxt)); } void link(int u,int v,int l) { nxt[++cnt]=head[u]; head[u]=cnt; to[cnt]=v; w[cnt]=l; } void spfa(int s) { queue<int>q; memset(d,inf,sizeof(d)); q.push(s); d[s]=0; used[s]=1; while(!q.empty()) { int u=q.front(); q.pop(); used[u]=0; for(int i=head[u];~i;i=nxt[i]) { int v=to[i],val=w[i]; if(d[v]>d[u]+val) { d[v]=d[u]+val; if(!used[v]) { q.push(v); used[v]=1; } } } } int tot=0; for(int i=1;i<=n;i++) { tot+=d[pos[i]]; } ans=Min(ans,tot); } int main() { scanf("%d%d%d",&n,&p,&e); for(int i=1;i<=n;i++) { int u; scanf("%d",&pos[i]); } Init(); for(int i=1;i<=e;i++) { int u,v,c; scanf("%d%d%d",&u,&v,&c); link(u,v,c); link(v,u,c); } for(int i=1;i<=p;i++) { spfa(i); } printf("%d",ans); return 0; }
lca 1787
#include<iostream> #include<stdio.h> #include<cstring> using namespace std; int n,m,u,v,a,b,c,ans,temp1,cnt=-1; int dep[1000010],head[1000010],to[1000010],nxt[1000010]; int fa[23][1000010]; void Init() { memset(head,-1,sizeof(head)); memset(nxt,-1,sizeof(nxt)); memset(fa,-1,sizeof(fa)); } int abs(int x) { return x>0?x:-x; } void link(int u,int v) { nxt[++cnt]=head[u]; head[u]=cnt; to[cnt]=v; } void dfs(int u,int d) { dep[u]=d; for(int i=head[u];~i;i=nxt[i]) { int v=to[i]; if(!dep[v]) { fa[0][v]=u; dfs(v,d+1); } } } int lca(int u,int v) { if(dep[u]<dep[v]) swap(u,v); int deep=dep[u]-dep[v]; for(int i=22;i>=0;i--) { if(deep&(1<<i)) u=fa[i][u]; } if(u==v) return u; for(int i=22;i>=0;i--) { if(fa[i][u]!=fa[i][v]) { u=fa[i][u]; v=fa[i][v]; } } return fa[0][u]; } inline int calc(int x,int y) { int temp=lca(x,y); return abs(dep[x]-dep[temp])+abs(dep[y]-dep[temp]); } int main() { scanf("%d%d",&n,&m); Init(); for(int i=1;i<n;i++) { int u,v; scanf("%d%d",&u,&v); link(u,v); link(v,u); } dfs(1,0); for(int i=1;i<=22;i++) { for(int j=1;j<=n;j++) { if(fa[i-1][j]!=-1) fa[i][j]=fa[i-1][fa[i-1][j]]; } } for(int i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&c); int x=lca(a,b); int y=lca(b,c); int z=lca(c,a); if(x==y) temp1=z; else if(y==z) temp1=x; else if(x==z) temp1=y; ans=calc(a,temp1)+calc(b,temp1)+calc(c,temp1); printf("%d %d\n",temp1,ans); } return 0; }
二分 跳石头
#include<iostream> #include<stdio.h> using namespace std; int n,m,ans,L; int a[500010],mark[500010]; bool C(int x) { int last=0,tot=0; for(int i=1;i<=n;i++) { mark[i]=0; if(a[i]-a[last]<x) { tot++; mark[i]=1; } else last=i; } last=n+1; for(int i=n;i>=1;i--) { if(a[last]-a[i]<x&&!mark[i]) tot++; else if(a[last]-a[i]>=x) break; } return tot<=m; } int main() { scanf("%d%d%d",&L,&n,&m); a[0]=0; a[n+1]=L+1; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } int l=0,r=L+1,mid; while(r-l>1) { mid=(l+r)/2; if(C(mid)) {l=mid;ans=mid;} else r=mid; } if(C(ans+1)) ans++; printf("%d",ans); return 0; }
线段树
1012
#include<iostream> #include<cstdio> using namespace std; const int inf=1<<29; int m,d,t,size; int tree[6000010]; int Max(int x,int y) { return x>y?x:y; } void update(int l,int r,int x,int pos,int num) { if(l==r) { tree[x]=num; return; } if(pos>(l+r)/2) update((l+r)/2+1,r,x*2+1,pos,num); if(pos<=(l+r)/2) update(l,(l+r)/2,x*2,pos,num); tree[x]=Max(tree[x],Max(tree[x*2],tree[x*2+1])); } int query(int l,int r,int x,int a,int b) { if(l>b||r<a) return -inf; if(l>=a&&r<=b) return tree[x]; return Max(query(l,(l+r)/2,x*2,a,b),query((l+r)/2+1,r,x*2+1,a,b)); } int main() { scanf("%d%d",&m,&d); for(int i=1;i<=m;i++) { char s[10]; scanf("%s",s); if(s[0]==‘A‘) { int n,num; scanf("%d",&n); size++; num=(n+t)%d; update(1,m,1,size,num); } else if(s[0]==‘Q‘) { int l; scanf("%d",&l); t=query(1,m,1,size-l+1,size); printf("%d\n",t); } } // for(int i=1;i<=3;i++) cout<<tree[i]<<" "; return 0; }
快速幂:
#include<iostream> using namespace std; int n,m,k,x; int power(int k) { int t=10,ret=1; while(k>0) { if(k%2==1) ret*=t; t*=t; k/=2; } return ret; } int main() { cin>>k; cout<<power(k); return 0; }
以上是关于noip复习模板的主要内容,如果未能解决你的问题,请参考以下文章