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);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章