Codeforces Round #635 (Div. 2)D+Codeforces Round #633 (Div. 2)D

D. Xenia and Colorful Gems

time limit per test3 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Xenia is a girl being born a noble. Due to the inflexibility and harshness of her family, Xenia has to find some ways to amuse herself.
Recently Xenia has bought nr red gems, ng green gems and nb blue gems. Each of the gems has a weight.
Now, she is going to pick three gems.
Xenia loves colorful things, so she will pick exactly one gem of each color.
Xenia loves balance, so she will try to pick gems with little difference in weight.
Specifically, supposing the weights of the picked gems are x, y and z, Xenia wants to find the minimum value of (x−y)2+(y−z)2+(z−x)2. As her dear friend, can you help her?
Input
The first line contains a single integer t (1≤t≤100) — the number of test cases. Then t test cases follow.
The first line of each test case contains three integers nr,ng,nb (1≤nr,ng,nb≤105) — the number of red gems, green gems and blue gems respectively.
The second line of each test case contains nr integers r1,r2,…,rnr (1≤ri≤109) — ri is the weight of the i-th red gem.
The third line of each test case contains ng integers g1,g2,…,gng (1≤gi≤109) — gi is the weight of the i-th green gem.
The fourth line of each test case contains nb integers b1,b2,…,bnb (1≤bi≤109) — bi is the weight of the i-th blue gem.
It is guaranteed that ∑nr≤105, ∑ng≤105, ∑nb≤105 (the sum for all test cases).
Output
For each test case, print a line contains one integer — the minimum value which Xenia wants to find.
Example
inputCopy
5
2 2 3
7 8
6 3
3 1 4
1 1 1
1
1
1000000000
2 2 2
1 2
5 4
6 7
2 2 2
1 2
3 4
6 7
3 4 1
3 2 1
7 3 3 4
6
outputCopy
14
1999999996000000002
24
24
14
Note
In the first test case, Xenia has the following gems:
If she picks the red gem with weight 7, the green gem with weight 6, and the blue gem with weight 4, she will achieve the most balanced selection with (x−y)2+(y−z)2+(z−x)2=(7−6)2+(6−4)2+(4−7)2=14.
题意
分别给定n、m、k个数组,在这个三个数组里面分别选去取三个数x,y,z,使得(x-y) * (x-y)+(x-z) * (x-z)+(y-k) * (y-z)的值最小
思路
先确定最大的x和最小的z,然后枚举y,更新min值
来自巨佬

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std; 
typedef long long ll;
const int maxn=1e5+100;
ll a[maxn],b[maxn],c[maxn];
ll fun(ll a[],int n,ll b[],int m,ll c[],int k)
{
	ll ans=4e18;//满足:c[i]<=a[i]<=b[i] 
	int l,r,mid,bi,ci;
	for(int i=1;i<n;i++)//枚举a[i] 
	{
		if(c[1]>a[i])continue;
		bi=lower_bound(b+1,b+1+m,a[i])-b;
		if(b[bi]==4e18)continue;
		l=1,r=k;
		while(l<=r)
		{
			mid=(l+r)/2;
			if(c[mid]<=a[i])
			{
				l=mid+1;ci=mid;
			}
			else r=mid-1;
		}
		ans=min(ans,(a[i]-b[bi])*(a[i]-b[bi])+(a[i]-c[ci])*(a[i]-c[ci])+(b[bi]-c[ci])*(b[bi]-c[ci]));
	}
	return ans;
}
int main()
{
	int n,m,k,t;
	cin>>t;
	ll ans;
	while(t--)
	{
		scanf("%d%d%d",&n,&m,&k);
		for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
		for(int i=1;i<=m;i++)scanf("%lld",&b[i]);
		for(int i=1;i<=k;i++)scanf("%lld",&c[i]);
		sort(a+1,a+1+n);sort(b+1,b+1+m);sort(c+1,c+1+k);
		ans=a[n+1]=b[m+1]=c[k+1]=4e18;
		
		ans=min(ans,fun(a,n+1,b,m+1,c,k+1));
		ans=min(ans,fun(a,n+1,c,k+1,b,m+1));
		ans=min(ans,fun(b,m+1,a,n+1,c,k+1));
		ans=min(ans,fun(b,m+1,c,k+1,a,n+1));
		ans=min(ans,fun(c,k+1,b,m+1,a,n+1));
		ans=min(ans,fun(c,k+1,a,n+1,b,m+1));
		cout<<ans<<endl;
	}
}

D. Edge Weight Assignment

You have unweighted tree of n vertices. You have to assign a positive weight to each edge so that the following condition would hold:

For every two different leaves v1 and v2 of this tree, bitwise XOR of weights of all edges on the simple path between v1 and v2 has to be equal to 0.
Note that you can put very large positive integers (like 10(1010)).

It’s guaranteed that such assignment always exists under given constraints. Now let’s define f as the number of distinct weights in assignment.

In this example, assignment is valid, because bitwise XOR of all edge weights between every pair of leaves is 0. f value is 2 here, because there are 2 distinct edge weights(4 and 5).
In this example, assignment is invalid, because bitwise XOR of all edge weights between vertex 1 and vertex 6 (3,4,5,4) is not 0.

What are the minimum and the maximum possible values of f for the given tree? Find and print both.

Input
The first line contains integer n (3≤n≤105) — the number of vertices in given tree.

The i-th of the next n−1 lines contains two integers ai and bi (1≤ai<bi≤n) — it means there is an edge between ai and bi. It is guaranteed that given graph forms tree of n vertices.

Output
Print two integers — the minimum and maximum possible value of f can be made from valid assignment of given tree. Note that it’s always possible to make an assignment under given constraints.

Examples
inputCopy
6
1 3
2 3
3 4
4 5
5 6
outputCopy
1 4
inputCopy
6
1 3
2 3
3 4
4 5
4 6
outputCopy
3 3
inputCopy
7
1 2
2 7
3 4
4 7
5 6
6 7
outputCopy
1 6
Note
In the first example, possible assignments for each minimum and maximum are described in picture below. Of course, there are multiple possible assignments for each minimum and maximum.

In the second example, possible assignments for each minimum and maximum are described in picture below. The f value of valid assignment of this tree is always 3.

In the third example, possible assignments for each minimum and maximum are described in picture below. Of course, there are multiple possible assignments for each minimum and maximum.

题意
题意给你一棵树,要你计算出对于任意的两个叶子节点他们之间的路径异或和等于0一种的树最多和最少的权值不同的边的数量
思路
最小值:根据样例可知,如果任意两个节点的距离为偶数,则他们XOR的结果为0可选的最小数字为1,否则为0
最大值:同样可以从样例得提示里面得出,n个节点可以选n个不同的数,除了两个节点的父节点相同的情况,如图1、2、3节点,1、2的父节点同为3,则1、2的距离为2,是偶数则1、2必须相等。
在这里插入图片描述
在这里插入图片描述
code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
using namespace std; 
typedef long long ll;
vector<int>v[100010];
int t[100010];//统计节点数,如果为1则表示为底节点
int d[100010];
int flag[100010];
void dfs(int now,int last,int d[])
{
	d[now]=d[last]+1;
	for(int i=0;i<v[now].size();i++)
	{
		if(v[now][i]!=last)
		{
			dfs(v[now][i],now,d);
		}
	}
}
int main()
{
	int n,a,b;cin>>n;
	for(int i=1;i<n;i++)
	{
		scanf("%d%d",&a,&b);
		t[a]++;t[b]++; 
		v[a].push_back(b);
		v[b].push_back(a);
	}
	for(int i=1;i<=n;i++)
	{
		if(t[i]==1)flag[v[i][0]]++;//入度为1,表示为底部节点,底部节点对应得父节点可以为任意数字 
	}
	d[0]=0;
	dfs(1,0,d);
	int ans=0,ans2=1,odd=0,even=0;
	map<int,int>m;
	for(int i=1;i<=n;i++)
	{
		if(t[i]==1)
		{
			if(d[i]%2==0)even++;
			else odd++;
			if(flag[v[i][0]]==1)
			ans++;
			else
			{
				m[v[i][0]]=1;
			}
		}
		else ans++;
	}
	if(even&&odd)ans2+=2;
	ans+=m.size();
	printf("%d %d\n",ans2,ans-1);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值