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;
}
View Code

 

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;
}
View Code

 

posted @ 2020-04-22 00:26  Y-KnightQin  阅读(118)  评论(0编辑  收藏  举报