round 635
AB水题
C
我们可以得知,选取一个点做为工业城市,要使得答案最优,就要优先选择深度大的点,而对于一个点,如果选择了该点,那么其子树中的所有点肯定均被选择了,那么子树选择了的点对当前点是会有影响的。
什么影响呢?选择此点,子树中所有点的贡献都会 −1,那么我们可以定义该点的贡献为 此点深度-儿子个数+1 (depth[v]−sz[v]+1) ,对于要选k个这样的点,要使答案最大,只需按照每个点的depth[v]−sz[v]的大小顺序排序即可。
#include <bits/stdc++.h> #define debug freopen("r.txt","r",stdin) #define mp make_pair #define ri register int using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 4e5+5; const int INF = 0x3f3f3f3f; const int mod = 998244353; inline ll read(){ll s=0,w=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w;} ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;} struct node { int dep,son; }; vector <int> G[maxn]; ll ans; int n,k,i,x,y; node a[maxn]; void dfs(int u,int father) { a[u].son+=1; for (auto v:G[u]) { if (v==father) continue; a[v].dep=a[u].dep+1; dfs(v,u); a[u].son+=a[v].son; } } bool cmp(node x,node y) { return x.dep-x.son>y.dep-y.son; } int main() { // debug; n=read(),k=read(); for (i=1;i<n;i++) { x=read(),y=read(); G[x].push_back(y); G[y].push_back(x); } // for (i=1;i<=n;i++) a[i].num=i; a[1].dep=1; dfs(1,0); sort(a+1,a+1+n,cmp); for (i=1;i<=k;i++) { ans+=a[i].dep-a[i].son; } cout<<ans<<endl; return 0; }
D
假设选出的三个数,不论它们来自哪个数组,定为 x ,y ,z,(x<=y<=z),我们枚举来自某个数组里面的y,通过二分,即可得到比 y 小于等于的最大数x,和比 y 大于等于的最小数z。
x ,y ,z分别来自哪个数组呢?三个数组轮流暴力枚举即可。
#include <bits/stdc++.h> #define debug freopen("r.txt","r",stdin) #define mp make_pair #define ri register int using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 1e5+10; const ll INF = 0x7fffffffffffffff; const int mod = 998244353; inline ll read(){ll s=0,w=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w;} int t,x,y,z,i,k; ll ans; vector <ll> a,b,c; void solve(vector <ll> a,vector <ll> b,vector <ll> c) { for(auto y:b) { auto z=lower_bound(c.begin(), c.end(), y); auto x=upper_bound(a.begin(), a.end(), y); if(x==a.begin() || z==c.end()) continue; x--; ans=min(ans, (y-*z)*(y-*z)+(*x-y)*(*x-y)+(*z-*x)*(*z-*x)); } } int main() { // debug; t=read(); while (t--) { x=read(),y=read(),z=read(); for (i=1;i<=x;i++) k=read(),a.push_back(k); for (i=1;i<=y;i++) k=read(),b.push_back(k); for (i=1;i<=z;i++) k=read(),c.push_back(k); sort(a.begin(),a.end()); sort(b.begin(),b.end()); sort(c.begin(),c.end()); ans=INF; solve(a,b,c);solve(a,c,b); solve(b,a,c);solve(b,c,a); solve(c,a,b);solve(c,b,a); cout<<ans<<endl; a.clear(),b.clear(),c.clear(); } return 0; }