T1:LCA
Code(倍增):
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<queue> 5 #define MN 500005 6 #define L 20 7 using namespace std; 8 inline int in(){ 9 int x=0;bool f=0; char c; 10 for (;(c=getchar())<'0'||c>'9';f=c=='-'); 11 for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0'); 12 return f?-x:x; 13 } 14 struct edge{ 15 int to,next; 16 }e[MN]; 17 queue<int>q; 18 int fa[MN][L+1],head[MN],dep[MN]; 19 bool vis[MN]; 20 int cnt=0,rt=0,n,qu,x,y; 21 inline void ins(int x,int y){ 22 e[++cnt].to=y;e[cnt].next=head[x];head[x]=cnt; 23 } 24 inline void swap(int &a,int &b){a^=b;b^=a;a^=b;} 25 inline void bfs(int x){ 26 vis[x]=1;q.push(x); 27 while (!q.empty()){ 28 int u=q.front();q.pop(); 29 for (int i=head[u];i;i=e[i].next){ 30 int v=e[i].to; 31 if (!vis[v]) dep[v]=dep[u]+1,q.push(v); 32 } 33 } 34 } 35 inline void gf(){ 36 for (int j=1;j<=L;++j) 37 for (int i=1;i<=n;++i) fa[i][j]=fa[fa[i][j-1]][j-1]; 38 } 39 inline int lca(int u,int v){ 40 if (dep[u]<dep[v]) swap(u,v);int dif=dep[u]-dep[v]; 41 for (int i=0;i<L;++i) if (dif&(1<<i)) u=fa[u][i]; 42 if (u==v) return u;for (int i=L-1;i>=0;--i) 43 if (fa[u][i]!=fa[v][i]) {u=fa[u][i];v=fa[v][i];} 44 u=fa[u][0];return u; 45 } 46 int main() 47 { 48 n=in();qu=in(); 49 for (int i=1;i<n;++i){ 50 x=in();y=in();ins(x,y);fa[y][0]=x; 51 if (!fa[x][0]) rt=x; 52 }dep[rt]=1;bfs(rt);gf(); 53 for (int i=1;i<=qu;++i){x=in();y=in();printf("%d\n",lca(x,y));} 54 return 0; 55 }
Code(Tarjan):
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define Mx 500005 5 using namespace std; 6 struct edge{int to,next;}e[1500005]; 7 int h[Mx],q[Mx],f[Mx],a[Mx],cnt=0,n,m,c,b; 8 bool r[Mx]; 9 inline void ins(int *h,int x,int y){e[++cnt].to=y;e[cnt].next=h[x];h[x]=cnt;} 10 inline int ff(int x){return f[x]?f[x]=ff(f[x]):x;} 11 int tarjan(int u){ 12 for (int i=h[u];i;i=e[i].next){tarjan(e[i].to);f[e[i].to]=u;} 13 for (int i=q[u];i;i=e[i].next) 14 if(a[e[i].to]) a[e[i].to]=ff(a[e[i].to]); 15 else a[e[i].to]=u; 16 17 } 18 int main() 19 { 20 scanf("%d%d",&n,&m); 21 for(int i=1;i<n;i++){scanf("%d%d",&c,&b);ins(h,c,b);r[b]=1;} 22 for(int i=0;i<m;i++){scanf("%d%d",&c,&b);ins(q,c,i);ins(q,b,i);} 23 for(int i=1;i<=n;i++)if(!r[i]){tarjan(i);break;} 24 for(int i=0;i<m;i++)printf("%d\n",a[i]); 25 return 0; 26 }
Code(树链剖分):
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define Mx 500005 5 using namespace std; 6 struct edge{int to,next;}e[1500005]; 7 int h[Mx],q[Mx],f[Mx],a[Mx],cnt=0,n,m,c,b; 8 bool r[Mx]; 9 inline void ins(int *h,int x,int y){e[++cnt].to=y;e[cnt].next=h[x];h[x]=cnt;} 10 inline int ff(int x){return f[x]?f[x]=ff(f[x]):x;} 11 int tarjan(int u){ 12 for (int i=h[u];i;i=e[i].next){tarjan(e[i].to);f[e[i].to]=u;} 13 for (int i=q[u];i;i=e[i].next) 14 if(a[e[i].to]) a[e[i].to]=ff(a[e[i].to]); 15 else a[e[i].to]=u; 16 17 } 18 int main() 19 { 20 scanf("%d%d",&n,&m); 21 for(int i=1;i<n;i++){scanf("%d%d",&c,&b);ins(h,c,b);r[b]=1;} 22 for(int i=0;i<m;i++){scanf("%d%d",&c,&b);ins(q,c,i);ins(q,b,i);} 23 for(int i=1;i<=n;i++)if(!r[i]){tarjan(i);break;} 24 for(int i=0;i<m;i++)printf("%d\n",a[i]); 25 return 0; 26 }
T2:跳跳棋
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define inf 1000000000 5 using namespace std; 6 inline int in(){ 7 int x=0;bool f=0; char c; 8 for (;(c=getchar())<'0'||c>'9';f=c=='-'); 9 for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0'); 10 return f?-x:x; 11 } 12 struct hop{ 13 int p[3]; 14 }a,b,r1,r2; 15 inline bool operator !=(hop a,hop b){ 16 for (int i=0;i<3;++i) if (a.p[i]!=b.p[i]) return 1; 17 return 0; 18 } 19 int cnt=0,dep1,dep2,lca; 20 inline hop gcd (hop x,int dep){ 21 hop ans; 22 int d1=x.p[1]-x.p[0],d2=x.p[2]-x.p[1]; 23 memcpy(ans.p,x.p,sizeof(x.p));if (d1==d2) return ans; 24 if (d1<d2){ 25 int d=min(dep,(d2-1)/d1); 26 dep-=d;cnt+=d;ans.p[1]+=d*d1;ans.p[0]+=d*d1; 27 }else{ 28 int d=min(dep,(d1-1)/d2); 29 dep-=d;cnt+=d;ans.p[2]-=d*d2;ans.p[1]-=d*d2; 30 }if (dep>0) return gcd(ans,dep);else return ans; 31 } 32 int main() 33 { 34 for (int i=0;i<3;++i) a.p[i]=in();sort(a.p,a.p+3); 35 for (int i=0;i<3;++i) b.p[i]=in();sort(b.p,b.p+3); 36 r1=gcd(a,inf);dep1=cnt;cnt=0;r2=gcd(b,inf);dep2=cnt;cnt=0; 37 if (r1!=r2) {printf("NO");return 0;} 38 if (dep1>dep2) {swap(dep1,dep2);for (int i=0;i<3;++i)swap(a.p[i],b.p[i]);} 39 int ct=dep2-dep1;b=gcd(b,ct);int l=0,r=dep1; 40 while (l<=r){ 41 int mid=(l+r)>>1; 42 if (gcd(a,mid)!=gcd(b,mid)) l=mid+1;else lca=mid,r=mid-1; 43 }printf("YES\n%d",(lca<<1)+ct); 44 return 0; 45 }
T3:树的统计
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define L (x<<1) 5 #define R (x<<1|1) 6 #define mid ((l+r)>>1) 7 #define inf 0x7fffffff 8 #define MN 30005 9 #define MM (1<<16) 10 using namespace std; 11 inline int in(){ 12 int x=0;bool f=0; char c; 13 for (;(c=getchar())<'0'||c>'9';f=c=='-'); 14 for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0'); 15 return f?-x:x; 16 } 17 inline int max(int a,int b){return a>b?a:b;} 18 struct edge{ 19 int to,next; 20 }e[MN<<1]; 21 int head[MN],siz[MN],pos[MN],dep[MN],top[MN],son[MN],fa[MN]; 22 int sum[MM],mx[MM],cnt=0,dfn=0,n,q,x,y,u,v,M; 23 char op[7]; 24 inline void ins(int x,int y){ 25 e[++cnt].to=y;e[cnt].next=head[x];head[x]=cnt; 26 } 27 inline void pre(int u){ 28 siz[u]=1; 29 for (int i=head[u];i;i=e[i].next){ 30 int v=e[i].to; 31 if (v==fa[u]) continue; 32 fa[v]=u;dep[v]=dep[u]+1;pre(v);siz[u]+=siz[v]; 33 if (siz[v]>siz[son[u]]) son[u]=v; 34 } 35 } 36 inline void dfs(int u,int tp){ 37 top[u]=tp;pos[u]=(++dfn);if (son[u]) dfs(son[u],tp); 38 for (int i=head[u];i;i=e[i].next){ 39 int v=e[i].to; 40 if (v!=fa[u]&&v!=son[u]) dfs(v,v); 41 } 42 } 43 inline void up(int x){ 44 sum[x]=sum[L]+sum[R];mx[x]=max(mx[L],mx[R]); 45 } 46 inline void update(int x,int v){ 47 x+=M;sum[x]=mx[x]=v;for (x>>=1;x;x>>=1) up(x); 48 } 49 inline int qmax(int l,int r){ 50 int ans=-inf; 51 for (l+=M-1,r+=M+1;l^r^1;l>>=1,r>>=1){ 52 if (~l&1) ans=max(ans,mx[l^1]); 53 if ( r&1) ans=max(ans,mx[r^1]); 54 }return ans; 55 } 56 inline int qsum(int l,int r){ 57 int ans=0; 58 for (l+=M-1,r+=M+1;l^r^1;l>>=1,r>>=1){ 59 if (~l&1) ans+=sum[l^1]; 60 if ( r&1) ans+=sum[r^1]; 61 }return ans; 62 } 63 inline int querym(int x,int y){ 64 int ans=-inf; 65 while (top[x]!=top[y]){ 66 if (dep[top[x]]>dep[top[y]]) ans=max(ans,qmax(pos[top[x]],pos[x])),x=fa[top[x]]; 67 else ans=max(ans,qmax(pos[top[y]],pos[y])),y=fa[top[y]]; 68 }if (dep[x]<dep[y]) ans=max(ans,qmax(pos[x],pos[y])); 69 else ans=max(ans,qmax(pos[y],pos[x]));return ans; 70 } 71 inline int querys(int x,int y){ 72 int ans=0; 73 while (top[x]!=top[y]){ 74 if (dep[top[x]]>dep[top[y]]) ans+=qsum(pos[top[x]],pos[x]),x=fa[top[x]]; 75 else ans+=qsum(pos[top[y]],pos[y]),y=fa[top[y]]; 76 }if (dep[x]<dep[y]) ans+=qsum(pos[x],pos[y]); 77 else ans+=qsum(pos[y],pos[x]);return ans; 78 } 79 int main() 80 { 81 n=in();for (M=1;M<n+2;M<<=1); 82 for (int i=1;i<n;++i){ 83 x=in();y=in();ins(x,y);ins(y,x); 84 }fa[1]=1;dep[1]=1;pre(1);dfs(1,1); 85 for (int i=1;i<=n;++i) sum[M+pos[i]]=mx[M+pos[i]]=in(); 86 for (int i=M-1;i;--i) up(i);q=in(); 87 for (int i=1;i<=q;++i){ 88 scanf("%s",op);u=in();v=in(); 89 if (op[1]=='H') update(pos[u],v); 90 else if (op[1]=='M') printf("%d\n",querym(u,v)); 91 else if (op[1]=='S') printf("%d\n",querys(u,v)); 92 }return 0; 93 }
T4:货车运输
Code:
1 #include<iostream> 2 #include<cmath> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<vector> 7 #include<queue> 8 #include<algorithm> 9 #define inf 0x7fffffff 10 using namespace std; 11 int fa[18][10005],dep[10005],dis[18][10005],head[10005],f[10005]; 12 int n,m,q,x,y,l,cnt,cur; 13 bool vis[10005]; 14 const int maxpow=16; 15 struct edge{int to,next,val;}e[20005]; 16 struct edg{int a,b,v;}ed[50005]; 17 bool cmp(edg a,edg b){return a.v>b.v;} 18 void ins(int x,int y,int v) 19 {e[++cnt].to=y;e[cnt].next=head[x];head[x]=cnt;e[cnt].val=v;} 20 int ff(int x){return f[x]==x?x:f[x]=ff(f[x]);} 21 void kruskal() 22 { 23 sort(ed+1,ed+m+1,cmp); 24 for (int i=1;i<=m;i++){ 25 edg eg=ed[i];int af=ff(eg.a),bf=ff(eg.b); 26 if (af!=bf){ 27 f[af]=bf;ins(eg.a,eg.b,eg.v);ins(eg.b,eg.a,eg.v); 28 cur++;if (cur==n-1) break; 29 } 30 } 31 } 32 void dfs(int u) 33 { 34 vis[u]=true; 35 for (int i=1;i<=maxpow;i++) 36 { 37 if (dep[u]<(1<<i)) break;fa[i][u]=fa[i-1][fa[i-1][u]]; 38 dis[i][u]=min(dis[i-1][u],dis[i-1][fa[i-1][u]]); 39 } 40 for (int i=head[u];i;i=e[i].next) 41 { 42 int v=e[i].to; 43 if (vis[v]) continue; 44 dep[v]=dep[u]+1;dis[0][v]=e[i].val; 45 fa[0][v]=u;dfs(v); 46 } 47 } 48 int lca(int u,int v) 49 { 50 if (dep[u]<dep[v]) swap(u,v); 51 int dif=dep[u]-dep[v]; 52 for (int i=0;i<=maxpow;i++) if ((1<<i)&dif) u=fa[i][u]; 53 for (int i=maxpow;i>=0;i--) 54 if (fa[i][u]!=fa[i][v]) {u=fa[i][u];v=fa[i][v];} 55 if (u==v) return u; 56 return fa[0][u]; 57 } 58 int fmn(int a,int b) 59 { 60 int mn=inf,diff=dep[a]-dep[b]; 61 for (int i=0;i<=maxpow;i++) 62 if (diff&(1<<i)){mn=min(mn,dis[i][a]);a=fa[i][a];}return mn; 63 } 64 int main() 65 { 66 scanf("%d%d",&n,&m); 67 memset(dis,127/3,sizeof(dis));for (int i=1;i<=n;i++) f[i]=i; 68 for(int i=1;i<=m;i++) 69 scanf("%d%d%d",&ed[i].a,&ed[i].b,&ed[i].v);kruskal(); 70 for (int i=1;i<=n;i++) if (!vis[i])dfs(i);scanf("%d",&q); 71 for (int i=1;i<=q;i++) 72 { 73 scanf("%d%d",&x,&y); 74 if (ff(x)!=ff(y)) {printf("-1\n");continue;} 75 int anc=lca(x,y); 76 printf("%d\n",min(fmn(x,anc),fmn(y,anc))); 77 } 78 return 0; 79 }
T5:软件包管理器
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define L (x<<1) 5 #define R (x<<1|1) 6 #define mid ((l+r)>>1) 7 #define MN 100005 8 #define MM (1<<18) 9 using namespace std; 10 inline int in(){ 11 int x=0;bool f=0; char c; 12 for (;(c=getchar())<'0'||c>'9';f=c=='-'); 13 for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0'); 14 return f?-x:x; 15 } 16 struct edge{ 17 int to,next; 18 }e[MN]; 19 int lazy[MM],sum[MM]; 20 int fa[MN],siz[MN],dep[MN],son[MN],head[MN],top[MN],rps[MN],pos[MN]; 21 int n,q,x,cnt=0,dfn=0; 22 char op[10]; 23 inline void ins(int x,int y){ 24 e[++cnt].to=y;e[cnt].next=head[x];head[x]=cnt; 25 } 26 inline void pre(int u){ 27 siz[u]=1; 28 for (int i=head[u];i;i=e[i].next){ 29 int v=e[i].to; 30 dep[v]=dep[u]+1;pre(v);siz[u]+=siz[v]; 31 if (son[u]==-1||siz[v]>siz[son[u]]) son[u]=v; 32 } 33 } 34 inline void dfs(int u,int tp){ 35 top[u]=tp;pos[u]=(++dfn);if (son[u]!=-1) dfs(son[u],tp); 36 for (int i=head[u];i;i=e[i].next){ 37 int v=e[i].to;if (v!=son[u]) dfs(v,v); 38 }rps[u]=dfn; 39 } 40 inline void up(int x){sum[x]=sum[L]+sum[R];} 41 inline void pushdown(int x,int l,int r){ 42 if (l==r||lazy[x]==-1) return;int M=r-l+1; 43 sum[L]=(M-(M>>1))*lazy[x];sum[R]=(M>>1)*lazy[x]; 44 lazy[L]=lazy[R]=lazy[x];lazy[x]=-1; 45 } 46 inline void update(int x,int l,int r,int a,int b,int v){ 47 if (a<=l&&b>=r){int M=r-l+1;lazy[x]=v;sum[x]=M*v;return;}pushdown(x,l,r); 48 if (a<=mid) update(L,l,mid,a,b,v);if (b>mid) update(R,mid+1,r,a,b,v);up(x); 49 } 50 inline int query(int x,int l,int r,int a,int b){ 51 if (a==l&&b==r) return sum[x];pushdown(x,l,r); 52 if (b<=mid) return query(L,l,mid,a,b);if (a>mid) return query(R,mid+1,r,a,b); 53 return query(L,l,mid,a,mid)+query(R,mid+1,r,mid+1,b); 54 } 55 inline int inst(int x){ 56 int ans=0;while (top[x]){ 57 ans+=pos[x]-pos[top[x]]+1-query(1,1,n,pos[top[x]],pos[x]); 58 update(1,1,n,pos[top[x]],pos[x],1);x=fa[top[x]]; 59 }ans+=pos[x]-query(1,1,n,1,pos[x]);update(1,1,n,1,pos[x],1);return ans; 60 } 61 inline int unin(int x){ 62 int ans=0;ans=query(1,1,n,pos[x],rps[x]); 63 update(1,1,n,pos[x],rps[x],0);return ans; 64 } 65 int main() 66 { 67 n=in();memset(son,-1,sizeof(son)); 68 for (int i=1;i<n;++i) fa[i]=in(),ins(fa[i],i); 69 fa[0]=0;dep[0]=1;pre(0);dfs(0,0);q=in(); 70 for (int i=1;i<=q;++i){ 71 scanf("%s",op);x=in(); 72 if (op[0]=='i') printf("%d\n",inst(x)); 73 if (op[0]=='u') printf("%d\n",unin(x)); 74 }return 0; 75 }