The 2022 ICPC Asia Hangzhou Regional Programming Contest
题解:
https://files.cnblogs.com/files/clrs97/2022ICPCHangzhouTutorial.pdf
Code:
A. Modulo Ruins the Legend
#include<bits/stdc++.h> using namespace std; int n,m; int exgcd(int a,int b,int &x,int &y) { if(!b) { x=1,y=0; return a; } int g=exgcd(b,a%b,y,x); y-=a/b*x; return g; } int main() { scanf("%d%d",&n,&m); int s=0; for(int i=1,x;i<=n;i++) { scanf("%d",&x); s=(s+x)%m; } //an - bm = g int a,b; int t=n%2==1?n:n/2; int g=exgcd(t,m,a,b); //a * n int k=s%g,x=(k-s)/g; x=1ll*x*a%m; if(x<0) x+=m; printf("%d\n",k); if(n%2==0) { if(x%2==0) printf("%d %d\n",x/2,0); else printf("%d %d\n",(((x-1)/2-n/2)%m+m)%m,1%m); } else printf("%d %d\n",x,0); }
B. Useful Algorithm
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=3e5+1e3+7; int n,m,q; int c[N],d[N],w[21]; int cnt,rt[21]; struct Tree{ #define ls (x<<1) #define rs (x<<1|1) struct T{ int mx; int v[2]; }; vector<T>t; void update(int x) { t[x].mx=max({t[ls].mx,t[rs].mx,t[ls].v[1]+t[rs].v[0]}); t[x].v[0]=max(t[ls].v[0],t[rs].v[0]); t[x].v[1]=max(t[ls].v[1],t[rs].v[1]); } void build(int x,int l,int r) { if(x==1) t.resize(r*4+1); if(l==r) { t[x].mx=-2e9; t[x].v[0]=t[x].v[1]=-1e9; return; } int mid=(l+r)>>1; build(ls,l,mid); build(rs,mid+1,r); update(x); } void change(int x,int p,int a,int b,int l,int r) { if(l==r) { t[x].v[a]=b; t[x].mx=t[x].v[0]+t[x].v[1]; return; } int mid=(l+r)>>1; if(p<=mid) change(ls,p,a,b,l,mid); else change(rs,p,a,b,mid+1,r); update(x); } #undef ls #undef rs }tr[21]; struct MXH{ priority_queue<int>q,dq; void insert(int x) { q.push(x); } void erase(int x) { dq.push(x); } int top() { while(q.size()&&dq.size()) { if(q.top()==dq.top()) q.pop(),dq.pop(); else break; } if(q.size()) return q.top(); else return -1e9; } }; vector<MXH>s[21]; int get(MXH &s) { return s.top(); } ll calc() { ll ret=0; for(int i=1;i<=m;i++) ret=max(ret,1ll*tr[i].t[1].mx*w[i]); return ret; } int main() { ios::sync_with_stdio(false); cin.tie(0); cin>>n>>m>>q; for(int i=1;i<=m;i++) cin>>w[i]; for(int i=1;i<=n;i++) cin>>c[i]; for(int i=1;i<=n;i++) cin>>d[i]; for(int i=1;i<=m;i++) s[i].resize(1<<i); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) s[j][c[i]%(1<<j)].insert(d[i]); for(int i=1;i<=m;i++) { tr[i].build(1,0,1<<i); for(int j=0;j<(1<<i);j++) { int mx=get(s[i][j]); if(mx<0) continue; tr[i].change(1,j,0,mx,0,(1<<i)); tr[i].change(1,(1<<i)-j,1,mx,0,(1<<i)); } } ll ans=calc(); cout<<ans<<"\n"; while(q--) { ll x,u,v; cin>>x>>u>>v; x^=ans,u^=ans,v^=ans; for(int i=1;i<=m;i++) { int p=c[x]%(1<<i); s[i][p].erase(d[x]); int mx=get(s[i][p]); tr[i].change(1,p,0,mx,0,(1<<i)); tr[i].change(1,(1<<i)-p,1,mx,0,(1<<i)); } c[x]=u; d[x]=v; for(int i=1;i<=m;i++) { int p=c[x]%(1<<i); s[i][p].insert(d[x]); int mx=get(s[i][p]); tr[i].change(1,p,0,mx,0,(1<<i)); tr[i].change(1,(1<<i)-p,1,mx,0,(1<<i)); } ans=calc(); cout<<ans<<"\n"; } }
C. No Bug No Game
#include<cstdio> const int N=3005,M=3005,V=15; int n,m,sum,i,j,k,x,t,sz,full,size[N],w[N][V],f[2][M]; inline void up(int&a,int b){a<b?(a=b):0;} int main(){ scanf("%d%d",&n,&m); for(i=1;i<=n;i++){ scanf("%d",&size[i]); sum+=size[i]; for(j=1;j<=size[i];j++)scanf("%d",&w[i][j]); } if(m>sum)m=sum; for(j=0;j<2;j++)for(k=0;k<=m;k++)f[j][k]=-1; f[0][0]=0; for(i=1;i<=n;i++){ sz=size[i]; full=w[i][size[i]]; for(j=1;~j;j--)for(k=m;~k;k--){ t=f[j][k]; if(t<0)continue; if(k+sz<=m)up(f[j][k+sz],t+full); if(j)continue; for(x=0;x<=sz&&k+x<=m;x++)up(f[1][k+x],t+w[i][x]); } } printf("%d",f[1][m]); }
D. Money Game
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=5e5+1e3+7; int n,a[N]; int main() { scanf("%d",&n); long long s=0; for(int i=1;i<=n;i++) scanf("%d",&a[i]),s+=a[i]; for(int i=1;i<=n;i++) printf("%.15lf%c",1.0*s*((i==1)+1)/(n+1)," \n"[i==n]); }
E. Oscar is All You Need
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e3+1e2+7; int T,n; int a[N],b[N],c; typedef pair<int,int> pii; vector<pii>ans; void opt(int x,int y) { assert(x>0&&y>0&&x+y<n); c=0; for(int i=n-y+1;i<=n;i++) b[++c]=a[i]; for(int i=x+1;i<=n-y;i++) b[++c]=a[i]; for(int i=1;i<=x;i++) b[++c]=a[i]; for(int i=1;i<=n;i++) a[i]=b[i]; ans.push_back({x,y}); } int main() { scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); ans.clear(); if(n==3) { vector<pii>ans; if(a[1]>a[3]) opt(1,1); } else { if(a[1]!=1) { int pos=1; for(int i=2;i<=n;i++) if(a[i]==1) pos=i; if(pos==2) { opt(2,1); opt(1,1); } else opt(1,n-pos+1); assert(a[1]==1); } for(int i=2;i<=n-2;i++) { if(a[i]==i) continue; int pos=-1; for(int j=i+1;j<=n;j++) if(a[j]==i) pos=j; assert(pos!=-1); if(pos!=i+1) { opt(i-1,n-pos+2); opt(1,i-1); } else { opt(i-1,1); opt(2,i-1); } } if(a[n-1]==n) { //1, 2, ..., n - 2, n, n - 1 opt(1,1); //n-1 , 2, ..., n - 2, n, 1 opt(n-2,1); //1, n, n-1, 2, ..., n - 2 opt(2,n-3); //2, ..., n-2, n-1, 1, n opt(n-3,1); //n, n-1, 1, 2, ..., n-2 opt(1,n-2); //1, 2, ..., n-2, n-1, n } for(int i=1;i<=n;i++) assert(a[i]==i); } printf("%d\n",(int)ans.size()); for(auto [x,y]:ans) printf("%d %d\n",x,y); } }
F. Da Mi Lao Shi Ai Kan De
#include<bits/stdc++.h> #define ll long long using namespace std; int n; map<string, int>mp; int main() { ios_base::sync_with_stdio(false); int Tcase; cin>>Tcase; while(Tcase--) { int num=0; cin>>n; for(int i=1;i<=n;i++) { string str; cin>>str; int L=str.size(); int ok=0; for(int j=0;j+2<L;j++) { if(str[j]=='b' && str[j+1]=='i' && str[j+2]=='e') ok=1; } if( ok && mp.count(str) > 0 ) ok=0; if(ok) { cout<<str<<'\n'; mp[str]=1; num++; } } if(num==0) { cout<<"Time to play Genshin Impact, Teacher Rice!\n"; } } return 0; }
G. Subgraph Isomorphism
#include <bits/stdc++.h> using namespace std; vector<int> G[100005], sta; int n, m; bool vis[100005]; int dfs(int v, int p) { vis[v] = true; sta.push_back(v); for(auto u : G[v]) { if(u == p) continue; if(vis[u]) return u; else { int ret = dfs(u, v); if(ret != -1) return ret; } } sta.pop_back(); return -1; } map<vector<int>,int>MAP; int cnt; int hs[100005]; vector<int>tmp; void gen_hs(int v, int p) { int deg=0; for(auto u : G[v]) { if(u == p || vis[u]) continue; gen_hs(u, v); deg++; } tmp.resize(deg); deg=0; for(auto u : G[v]) { if(u == p || vis[u]) continue; tmp[deg++]=hs[u]; } sort(tmp.begin(),tmp.end()); int&o=MAP[tmp]; if(!o)o=++cnt; hs[v]=o; } void solve() { scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) G[i].clear(); for(int i = 0; i < m; i++) { int u, v; scanf("%d%d", &u, &v); G[u].push_back(v); G[v].push_back(u); } if(m > n) { printf("NO\n"); return; } if(m < n) { printf("YES\n"); return; } for(int i = 1; i <= n; i++) vis[i] = false; sta.clear(); int r = dfs(1, 0); for(int i = 0; i < (int)sta.size(); i++) if(sta[i] == r) { sta.erase(sta.begin(), sta.begin() + i); break; } for(int i = 1; i <= n; i++) vis[i] = false; for(auto v : sta) vis[v] = true; cnt=0; MAP.clear(); for(auto v : sta) gen_hs(v, 0); for(int i = 0; i < (int)sta.size(); i++) if(hs[sta[i]] != hs[sta[(i + 2) % (int)sta.size()]]) { printf("NO\n"); return; } printf("YES\n"); } int main() { int T; scanf("%d", &T); while(T --) solve(); return 0; }
H. RPG Pro League
#include<cstdio> #include<algorithm> #include<vector> #include<queue> using namespace std; typedef pair<int,int>P; typedef long long ll; const int N=100005; int n,q,i,j,S,x,y,mask[N],cost[N],pool[N],is[N]; int clim,num,adj[5],cnt[9],bound[257]; ll ans; priority_queue<P>used[9]; priority_queue<P,vector<P>,greater<P> >unused[9]; struct Lim{int mask,cap;}lim[17]; inline int cmp(int x,int y){return cost[x]<cost[y];} inline bool check(){ for(int i=1;i<=clim;i++){ int mask=lim[i].mask,cap=lim[i].cap; for(int j=1;j<8;j++)if(mask>>j&1){ cap-=cnt[j]; if(cap<=0)break; } if(cap>0)return 0; } return 1; } inline int getused(int S){ while(!used[S].empty()){ P t=used[S].top(); if(!is[t.second]||cost[t.second]!=t.first){ used[S].pop(); continue; } return t.second; } return 0; } inline int getunused(int S){ while(!unused[S].empty()){ P t=unused[S].top(); if(is[t.second]||cost[t.second]!=t.first){ unused[S].pop(); continue; } return t.second; } return 0; } inline void modify(int x,int y){ int S=mask[x],i,best,who=0; if(is[x]){ ans+=y-cost[x]; if(y<=cost[x]){ used[S].push(P(cost[x]=y,x)); return; } best=cost[x]=y; cnt[S]--; for(i=1;i<8;i++){ y=getunused(i); if(!y)continue; if(cost[y]>=best)continue; cnt[mask[y]]++; if(check())best=cost[y],who=y; cnt[mask[y]]--; } if(who){ is[x]=0; unused[S].push(P(cost[x],x)); ans+=best-cost[x]; cnt[mask[who]]++; is[who]=1; used[mask[who]].push(P(cost[who],who)); }else{ cnt[S]++; used[S].push(P(cost[x],x)); } }else{ if(y>=cost[x]){ unused[S].push(P(cost[x]=y,x)); return; } best=cost[x]=y; cnt[S]++; for(i=1;i<8;i++){ y=getused(i); if(!y)continue; if(cost[y]<=best)continue; cnt[mask[y]]--; if(check())best=cost[y],who=y; cnt[mask[y]]++; } if(who){ is[x]=1; used[S].push(P(cost[x],x)); ans+=cost[x]-best; cnt[mask[who]]--; is[who]=0; unused[mask[who]].push(P(cost[who],who)); }else{ cnt[S]--; unused[S].push(P(cost[x],x)); } } } int main(){ scanf("%d",&n); for(i=1;i<=n;i++){ char s[9]; scanf("%s%d",s,&cost[i]); for(j=0;s[j];j++){ if(s[j]=='D')mask[i]|=1; else if(s[j]=='S')mask[i]|=2; else mask[i]|=4; } cnt[mask[i]]++; } for(i=0;i<3;i++)for(j=1;j<8;j++)if(j>>i&1)adj[i]|=1<<j; adj[3]=adj[0]|adj[1]; num=n/4; for(S=1;S<1<<4;S++){ int T=0,sum=0; for(i=0;i<4;i++)if(S>>i&1)T|=adj[i]; for(i=1;i<8;i++)if(T>>i&1)sum+=cnt[i]; int pop=__builtin_popcount(S); num=min(num,sum/pop); bound[T]=max(bound[T],pop); } for(i=1;i<256;i++)if(bound[i]){ lim[++clim].mask=i; lim[clim].cap=num*bound[i]; } for(i=1;i<=n;i++)pool[i]=i; sort(pool+1,pool+n+1,cmp); for(i=n;i;i--){ x=pool[i]; cnt[mask[x]]--; if(!check()){ ans+=cost[x]; is[x]=1; cnt[mask[x]]++; used[mask[x]].push(P(cost[x],x)); }else unused[mask[x]].push(P(cost[x],x)); } scanf("%d",&q); while(q--)scanf("%d%d",&x,&y),modify(x,y),printf("%lld\n",ans); }
I. Guess Cycle Length
#include<bits/stdc++.h> using namespace std; constexpr int MAGIC_S=3333,MAGIC_B=3333; int main() { ios_base::sync_with_stdio(false); auto walk=[&](int x) { cout<<"walk "<<x<<endl; int y; cin>>y; return y; }; mt19937 rng(58); int maxx=0; for(int i=1;i<=MAGIC_S;i++) { int x=rng()%1000000001; maxx=max(maxx,walk(x)); } map<int,int> mp; for(int i=MAGIC_B-1;i>=0;i--) { int x=walk(1); if(mp.count(x)) { cout<<"guess "<<mp[x]-i<<endl; return 0; } mp[x]=i; } for(int i=0;i<MAGIC_B;i++) { int x; if(i==0)x=maxx; else x=MAGIC_B; int y=walk(x); if(mp.count(y)) { cout<<"guess "<<maxx+i*MAGIC_B+mp[y]<<endl; return 0; } } assert(0); return 0; }
J. Painting
#include<cstdio> #include<set> #include<algorithm> using namespace std; typedef long long ll; typedef pair<int,int>P; const int N=300005,K=19,inf=1000010; int f[N][K],d[N]; set<P>T; struct E{int k,b;}e[N]; ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} struct Frac{ ll up,down; Frac(){} Frac(ll _up,ll _down){ up=_up,down=_down; if(down<0)up*=-1,down*=-1; } void simplify(){ if(!up){down=1;return;} ll t=gcd(up>0?up:-up,down); up/=t,down/=t; } void show(){ simplify(); printf("%lld/%lld",up,down); } }; struct Point{ Frac x,y; Point(){} Point(Frac _x,Frac _y){x=_x,y=_y;} void show(){ putchar('('); x.show(); putchar(','); y.show(); putchar(')'); } }h[N]; inline Point intersection(const E&A,const E&B){ return Point(Frac(B.b-A.b,A.k-B.k),Frac(1LL*A.k*B.b-1LL*A.b*B.k,A.k-B.k)); //(v/v,v^2/v) } inline int sgn(const E&A,const Point&B){ Frac t(B.x.up*A.k+B.x.down*A.b,B.x.down); //(v^2,v) ll tmp=t.up*B.y.down-t.down*B.y.up; //t.up/t.down-y.up/y.down if(!tmp)return 0; return tmp>0?1:-1; //1 means line A is above point B } inline int lca(int x,int y){ if(d[x]<d[y])swap(x,y); for(int i=K-1;~i;i--)if(d[f[x][i]]>=d[y])x=f[x][i]; if(x==y)return x; for(int i=K-1;~i;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i]; return f[x][0]; } inline int find(const E&e,int x,int top,int t){ for(int j=K-1;~j;j--){ int o=f[x][j]; if(d[o]<=d[top])continue; if(sgn(e,h[o])*t>=0)x=o; } while(x!=top&&sgn(e,h[x])*t>=0)x=f[x][0]; if(x!=top&&sgn(e,h[x])*t<0)return x; return 0; } int main(){ int n,W; scanf("%d%d",&n,&W); e[n+1].b=0; h[n+1]=Point(Frac(1,1),Frac(0,1)); d[n+1]=1; T.insert(P(0,n+1)); e[n+2].b=0; h[n+2]=Point(Frac(1,1),Frac(inf,1)); d[n+2]=1; T.insert(P(inf,n+2)); for(int i=1;i<=n;i++){ int A,B,C; scanf("%d%d%d",&A,&B,&C); e[i].k=B-A; e[i].b=A; set<P>::iterator it=T.lower_bound(P(A,0)); int nxt=it->second; it--; int pre=it->second; if(C)T.insert(P(A,i)); int top=lca(pre,nxt); int fa=find(e[i],pre,top,1); if(!fa)fa=find(e[i],nxt,top,-1); if(!fa)fa=top; d[i]=d[fa]+1; f[i][0]=fa; if(!fa)h[i]=Point(Frac(1,1),Frac(B,1)); else{ h[i]=intersection(e[i],e[fa]); if(C)for(int j=1;j<K;j++)f[i][j]=f[f[i][j-1]][j-1]; } Point ans=h[i]; ans.x.up*=W; ans.show(); puts(""); } }
K. Master of Both
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1000050; const int maxd=26; int top=0; int son[maxn+50][maxd]; int sz[maxn+50]; int val[maxn+50]; ll cnt[maxd+5][maxd+5]; ll ans2=0; void ins(int x,const string &str,int pos,int len){ sz[x]++; if (pos==len){ val[x]++; ans2+=sz[x]-val[x]; return; } int now=str[pos]-'a'; for (int i=0;i<maxd;i++) if (i!=now && son[x][i]!=-1) cnt[now][i]+=sz[son[x][i]]; int& nxt=son[x][now]; if (nxt==-1) nxt=++top; ins(nxt,str,pos+1,len); } int n,Q; string str; int main(){ ios_base::sync_with_stdio(false); memset(son,-1,sizeof(son)); cin >> n >> Q; for (int i=1;i<=n;i++){ cin >> str; ins(0,str,0,str.length()); } for (;Q--;){ cin >> str; int len=str.length(); ll ans=ans2; for (int i=0;i<len;i++) for (int j=i+1;j<len;j++) ans+=cnt[str[i]-'a'][str[j]-'a']; cout << ans << "\n"; } return 0; }
L. Levenshtein Distance
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=200010,K=35; int k,n,m,cnt,i,j,x,y,z,Log[N<<1],f[K][K<<1],g[N],ans[K]; char a[N],b[N],s[N<<2]; namespace SA{ int n,rk[N<<2],sa[N<<2],h[N<<2],tmp[N<<2],cnt[N<<2],f[18][N<<1]; void suffixarray(int n,int m){ int i,j,k;n++; for(i=0;i<n;i++)cnt[rk[i]=s[i]]++; for(i=1;i<m;i++)cnt[i]+=cnt[i-1]; for(i=0;i<n;i++)sa[--cnt[rk[i]]]=i; for(k=1;k<=n;k<<=1){ for(i=0;i<n;i++){ j=sa[i]-k; if(j<0)j+=n; tmp[cnt[rk[j]]++]=j; } sa[tmp[cnt[0]=0]]=j=0; for(i=1;i<n;i++){ if(rk[tmp[i]]!=rk[tmp[i-1]]||rk[tmp[i]+k]!=rk[tmp[i-1]+k])cnt[++j]=i; sa[tmp[i]]=j; } memcpy(rk,sa,n*sizeof(int)); memcpy(sa,tmp,n*sizeof(int)); if(j>=n-1)break; } n--; for(j=rk[h[i=k=0]=0];i<n;i++,k++) while(~k&&s[i]!=s[sa[j-1]+k])h[j]=k--,j=rk[sa[j]+1]; for(i=1;i<=n;i++)f[0][i]=h[i]; for(j=1;(1<<j)<=n;j++)for(i=1;i+(1<<j)-1<=n;i++)f[j][i]=min(f[j-1][i],f[j-1][i+(1<<(j-1))]); } inline int ask(int x,int y){ x=rk[x],y=rk[y]; if(x>y)swap(x,y); int k=Log[y-x]; return min(f[k][x+1],f[k][y-(1<<k)+1]); } } inline int lcp(int x,int y){ if(x>n||y>m)return 0; return SA::ask(x-1,y+n); } inline void umax(int&a,int b){a<b?(a=b):0;} inline void umin(int&a,int b){a>b?(a=b):0;} int main(){ scanf("%d%s%s",&k,b+1,a+1); n=strlen(a+1),m=strlen(b+1); for(i=1;i<=n;i++)s[cnt++]=a[i]; s[cnt++]='#'; for(i=1;i<=m;i++)s[cnt++]=b[i]; for(i=2;i<=cnt;i++)Log[i]=Log[i>>1]+1; SA::suffixarray(cnt,256); for(i=1;i<=n;i++){ if(n-i+1<m-k)break; for(j=m-k;j<=m+k;j++){ x=i+j-1; if(x>=i&&x<=n)g[x]=N; } for(j=0;j<=k;j++)for(x=-k;x<=k;x++)f[j][x+K]=0; f[0][K]=i; for(j=0;j<=k;j++)for(x=-k;x<=k;x++){ y=f[j][x+K]; if(!y)continue; z=y-i+x+1; y+=lcp(y,z); z=y-i+x+1; if(z>m)umin(g[y-1],j); if(j<k){ if(y<=n&&z<=m)umax(f[j+1][x+K],y+1); if(y<=n)umax(f[j+1][x+K-1],y+1); if(z<=m)umax(f[j+1][x+K+1],y); } } for(j=m+k;j>=m-k;j--){ x=i+j-1; if(x>=i&&x<=n){ if(x<n&&j<m+k)umin(g[x],g[x+1]+1); if(g[x]<=k)ans[g[x]]++; } } } for(i=0;i<=k;i++)printf("%d\n",ans[i]); }
M. Please Save Pigeland
#include<bits/stdc++.h> using namespace std; using pii=pair<int,int>; using ll=long long; const int N=5e5+1e3+7; int n,k,c[N],key[N]; vector<pii>g[N]; struct Data{ ll a,g; }; Data operator +(const Data &a,const Data &b) { if(b.a==-1) return a; if(a.a==-1) return b; return {a.a,__gcd(__gcd(a.g,b.g),abs(a.a-b.a))}; } Data operator +(const Data &a,ll b) { if(a.a==-1) return a; return {a.a+b,a.g}; } int sz[N]; ll d[N]; Data f[N]; void dfs(int x,int F) { f[x].a=-1; sz[x]=key[x]; for(auto [v,w]:g[x]) { if(v==F) continue; dfs(v,x); d[x]+=d[v]+1ll*w*sz[v]; sz[x]+=sz[v]; f[x]=f[x]+(f[v]+w); } if(key[x]) f[x]=f[x]+Data({0,0}); } ll ans; void go(int x,int F,Data G,ll D) { Data tG=G+f[x]; ll tD=D+d[x]; ll rG=__gcd(tG.a,tG.g); if(rG) ans=min(ans,tD/rG); else ans=min(ans,tD); // cout<<x<<" "<<tD<<endl; vector<Data>pf,sf; pf.push_back({-1,0}); for(int i=0;i<g[x].size();i++) { auto [v,w]=g[x][i]; if(v==F) continue; pf.push_back(pf.back()+(f[v]+w)); } sf.resize(pf.size()+1); sf.back()={-1,0}; int t=(int)sf.size()-2; for(int i=(int)g[x].size()-1;i>=0;i--) { auto [v,w]=g[x][i]; if(v==F) continue; sf[t]=sf[t+1]+(f[v]+w); t--; } t=0; for(int i=0;i<g[x].size();i++) { auto [v,w]=g[x][i]; if(v==F) continue; ++t; ll nD=D+d[x]-d[v]-1ll*sz[v]*w+1ll*(k-sz[v])*w; Data nG=(pf[t-1]+sf[t+1]+G)+w; if(key[x]) nG=(nG+Data{w,0}); go(v,x,nG,nD); } } int main() { scanf("%d%d",&n,&k); for(int i=1;i<=k;i++) scanf("%d",&c[i]),key[c[i]]=1; for(int i=1;i<n;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); g[u].push_back({v,w}); g[v].push_back({u,w}); } ans=3e18; dfs(1,0); go(1,0,{-1,0},0); printf("%lld\n",ans*2); } /* 5 3 3 4 5 1 2 2 2 3 4 2 5 4 3 4 6 */