Codeforces Round #636 (Div. 3)D+E

D - Constant Palindrome Sum

outputstandard output
You are given an array a consisting of n integers (it is guaranteed that n is even, i.e. divisible by 2). All ai does not exceed some integer k.
Your task is to replace the minimum number of elements (replacement is the following operation: choose some index i from 1 to n and replace ai with some integer in range [1;k]) to satisfy the following conditions:
after all replacements, all ai are positive integers not greater than k;
for all i from 1 to n2 the following equation is true: ai+an−i+1=x, where x should be the same for all n2 pairs of elements.
You have to answer t independent test cases.
Input
The first line of the input contains one integer t (1≤t≤104) — the number of test cases. Then t test cases follow.
The first line of the test case contains two integers n and k (2≤n≤2⋅105,1≤k≤2⋅105) — the length of a and the maximum possible value of some ai correspondingly. It is guratanteed that n is even (i.e. divisible by 2). The second line of the test case contains n integers a1,a2,…,an (1≤ai≤k), where ai is the i-th element of a.
It is guaranteed that the sum of n (as well as the sum of k) over all test cases does not exceed 2⋅105 (∑n≤2⋅105, ∑k≤2⋅105).
Output
For each test case, print the answer — the minimum number of elements you have to replace in a to satisfy the conditions from the problem statement.
Example
inputCopy
4
4 2
1 2 1 2
4 3
1 2 2 1
8 7
6 1 1 7 6 3 4 6
6 6
5 2 6 1 3 4
outputCopy
0
1
4
2
題意
把給定的數列的元素轉換成1~k範圍的數,使得任意i有:ai+a(n-i+1)=x,求最小的轉換次數
思路
x的範圍爲2~2*k
用差分數組計算每一個x需要的轉換次數,最後枚舉x求出min值

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string> 
#include<queue> 
#include<cmath>
using namespace std;
typedef long long ll;
priority_queue<int>ma;
priority_queue<int,vector<int>,greater<int> >mi;
int a[200010];
ll b[400010]; 
int main()
{
	int t,n,k;cin>>t;
	while(t--)
	{
		scanf("%d%d",&n,&k);
		memset(b,0,sizeof(b));
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&a[i]);
			if(i>n/2)
			{
				int sum=a[i]+a[n-i+1];
				int mi=min(a[i],a[n-i+1]);
				int ma=max(a[i],a[n-i+1]);
				b[2]+=2;b[mi+1]--;b[ma+k+1]++;b[sum]--;b[sum+1]++;
			}
		}
		ll ans=b[2];
		for(int i=3;i<=2*k;i++)
		{
			b[i]+=b[i-1];
			ans=min(b[i],ans);
		}
		printf("%lld\n",ans);
	}
	return 0;
}

E. Weights Distributing

outputstandard output
You are given an undirected unweighted graph consisting of n vertices and m edges (which represents the map of Bertown) and the array of prices p of length m. It is guaranteed that there is a path between each pair of vertices (districts).

Mike has planned a trip from the vertex (district) a to the vertex (district) b and then from the vertex (district) b to the vertex (district) c. He can visit the same district twice or more. But there is one issue: authorities of the city want to set a price for using the road so if someone goes along the road then he should pay the price corresponding to this road (he pays each time he goes along the road). The list of prices that will be used p is ready and they just want to distribute it between all roads in the town in such a way that each price from the array corresponds to exactly one road.

You are a good friend of Mike (and suddenly a mayor of Bertown) and want to help him to make his trip as cheap as possible. So, your task is to distribute prices between roads in such a way that if Mike chooses the optimal path then the price of the trip is the minimum possible. Note that you cannot rearrange prices after the start of the trip.

You have to answer t independent test cases.

Input
The first line of the input contains one integer t (1≤t≤104) — the number of test cases. Then t test cases follow.

The first line of the test case contains five integers n,m,a,b and c (2≤n≤2⋅105, n−1≤m≤min(n(n−1)2,2⋅105), 1≤a,b,c≤n) — the number of vertices, the number of edges and districts in Mike’s trip.

The second line of the test case contains m integers p1,p2,…,pm (1≤pi≤109), where pi is the i-th price from the array.

The following m lines of the test case denote edges: edge i is represented by a pair of integers vi, ui (1≤vi,ui≤n, ui≠vi), which are the indices of vertices connected by the edge. There are no loops or multiple edges in the given graph, i. e. for each pair (vi,ui) there are no other pairs (vi,ui) or (ui,vi) in the array of edges, and for each pair (vi,ui) the condition vi≠ui is satisfied. It is guaranteed that the given graph is connected.

It is guaranteed that the sum of n (as well as the sum of m) does not exceed 2⋅105 (∑n≤2⋅105, ∑m≤2⋅105).

Output
For each test case, print the answer — the minimum possible price of Mike’s trip if you distribute prices between edges optimally.

Example
inputCopy
2
4 3 2 3 4
1 2 3
1 2
1 3
1 4
7 9 1 5 7
2 10 4 8 5 6 7 3 3
1 2
1 3
1 4
3 2
3 5
4 2
5 6
1 7
6 7
outputCopy
7
12
Note
One of the possible solution to the first test case of the example:
在這裏插入圖片描述
One of the possible solution to the second test case of the example:

在這裏插入圖片描述
題意
給定m條邊的圖,給定m個權值讓你來安排權值在那條邊上,求點a到b,b到c的最小權值和
思路
分別求出a、b、c到所有點的路徑(邊的條數),最小值即a~x+2*(b ~ x)+c ~ x的權值和,即選取最小的權值給a、b、c到中間點x的邊上

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string> 
#include<queue> 
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
priority_queue<int>ma;
priority_queue<int,vector<int>,greater<int> >mi;
vector<int>T[200010];
ll sum[200010];
void bfs(int x,vector<int> &v)
{
	queue<int>q;
	v[x]=0;
	q.push(x);
	while(!q.empty())
	{
		int temp=q.front();q.pop();
		for(int i=0;i<T[temp].size();i++)
		//for(auto i:T[temp])
		{
			if(v[T[temp][i]]==INF)
			{
				v[T[temp][i]]=v[temp]+1;
				q.push(T[temp][i]);
			}
		}
	}
}
int main()
{
	int t,n,m,a,b,c,x,y;
	cin>>t;
	while(t--)
	{
		scanf("%d%d%d%d%d",&n,&m,&a,&b,&c);
		sum[0]=0;
		for(int i=1;i<=m;i++)
		{
			scanf("%lld",&sum[i]);
		}
		sort(sum+1,sum+1+m);
		for(int i=1;i<=m;i++)
		{
			sum[i]+=sum[i-1];
		}
		for(int i=1;i<=n;i++)T[i].clear();
		for(int i=1;i<=m;i++)
		{
			scanf("%d%d",&x,&y);
			T[x].push_back(y);T[y].push_back(x);
		}
		vector<int>la(n+1,INF);vector<int>lb(n+1,INF);vector<int>lc(n+1,INF);
		bfs(a,la);bfs(b,lb);bfs(c,lc);
		ll ans=1e18;
		for(int i=1;i<=n;i++)
		{
			if(la[i]+lb[i]+lc[i]<=m)
			{
				ans=min(ans,sum[lb[i]]+sum[la[i]+lb[i]+lc[i]]);
			}
		}
		printf("%lld\n",ans);
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章