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
*/

浙公網安備 33010602011771號