2017暑期集训Day 8

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
",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
",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
",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
%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
",querym(u,v));
91         else if (op[1]=='S') printf("%d
",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
");continue;}  
75         int anc=lca(x,y);  
76         printf("%d
",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
",inst(x));
73         if (op[0]=='u') printf("%d
",unin(x));
74     }return 0;
75 }
原文地址:https://www.cnblogs.com/codingutopia/p/2017summer_day8.html