首页 > 其他分享 >The 2nd Universal Cup. Stage 6: Warsaw L.Spectacle (思维)

The 2nd Universal Cup. Stage 6: Warsaw L.Spectacle (思维)

时间:2023-10-23 21:23:06浏览次数:27  
标签:下标 Cup int Universal rank 2nd 对战 差值 玩家

大致题意:

  给定n个玩家,每个玩家有一个战力值,安排 x (1 <= x <= n/2(向下取整))场游戏,每场游戏安排x对玩家对战,对于每一场游戏每个玩家只能参加一次对战,要求对于每x场玩家对战的两个玩家rating差的最大值尽可能小。

  例如给定6个玩家战力值为10 13 14 20 100 105,当x = 1的时候我们选择战力值为13 和 14的玩家进行对战最优,当x = 2的时候,我们选择13 和 14对战, 100和105对战最优(也可以是10 和 13对战, 100 和 105对战等等)

解题思路

  将玩家的rating排序后,可以发现这么个性质:一定是选择排完序之后的相邻玩家进行对战最优,因为他们的差值最小。

  所有的相邻玩家有n-1个差值,将这些差值和每个差值对应的两个下标提取出来按照差值进行排序,叫做rank数组,里面存储差值和差值对应的两个下标。下标从1开始。那么当我们统计x = 1的答案的时候,rank[1]里面存储的差值就是x = 1的时候的答案。

  那么当x = 2的时候,rank[2]里面的差值就是答案吗?

  稍加思考我们会发现并不是,如果有这种情况,rank[1]里面的两个下标为2和3,此时我们rank[2]里面存储的两个下标恰巧是3和4,如果我们要用下标3和下标4进行对战,那么下标2和下标3就不能进行对战。

  那么再思考如果rank[3]里面的下标恰巧是1和2的话,现在x = 2的答案会出现吗?

  会。此时我们让下标1和下标2对战,下标3和下标4对战。因为我们是按照差值大小排序的,那么x = 2的答案就是rank[3]里面存储的差值。这个时候可能就有人会想(其实是我自己会想)那我如何判断什么时候要拆开先前的组成的一对玩家换成遍历到的玩家进行对战呢。如果当前是要x-1和x打,在此之前我还存在这样的下标对战:1打2,2打3,3打4...,x-2打x-1,我又该如何抉择呢?

  其实很简单,我们只需要对先前遍历到玩家的时候,将他们丢进并查集,此时只要是两个大小为奇数的并查集进行合并,那么答案就会出现。

  假设在遍历到ranp[k]的时候x-1和x对战的时候已经存在1,2,3...,x-2这么一个集合。还存在x,x+1,x+2...这么一个集合。如果左边集合的大小为奇数,右边集合的大小为奇数,此时合并的话集合大小为偶数,而且这个合并完的集合我们可以让1和2对战,3和4对战...,此时答案就是rank[k]里面的差值。至于为什么,因为其他玩家对战的差值一定小于等于rank[k]里面的差值。如果左边集合大小为奇数右边集合大小为偶数很显然对战场数不会增加。很显然如果两个集合的大小是偶数也不会改变对战场次。

#include <bits/stdc++.h>

const int N = 2e5 + 10;
const int M = 1e6 + 10;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
using ll = long long;
typedef std::pair<ll, ll> PII;
typedef std::array<int, 3> a3;
#define ls u << 1
#define rs u << 1 | 1

int n, m;

long long a[N];
long long ans[N];

int father[N], sz[N];

inline int findset(int x) {
	return x == father[x] ? x : father[x] = findset(father[x]);
}

inline void solve() {
	std::cin >> n;

	for (int i = 1; i <= n; i ++) std::cin >> a[i];
	
	for (int i = 1; i <= n; i ++) father[i] = i, sz[i] = 1;

	std::sort(a + 1, a + n + 1);
	
	std::map<ll, std::vector<PII>> mp;
	for (int i = 2; i <= n; i ++)
		mp[a[i] - a[i - 1]].push_back({i - 1, i});
	
	int turn = 0;
	for (auto x: mp) {
		auto val = x.first;
		auto &tmp = x.second;
		for (auto &[x1, y1]: tmp) {
			x1 = findset(x1), y1 = findset(y1);
			father[x1] = y1;
			if ((sz[y1] & 1) && (sz[x1] & 1)) 
				ans[++ turn] = val;
			sz[y1] += sz[x1]; 
		}
	}
	
	for (int i = 1; i <= n / 2; i ++) std::cout << ans[i] << ' ';
}

int main(void) {
   std::ios::sync_with_stdio(false);
   std::cin.tie(0);
   std::cout.tie(0);
   
   int _ = 1;
   //std::cin >> _;
   while (_ --) solve();
   
   return 0;
}

标签:下标,Cup,int,Universal,rank,2nd,对战,差值,玩家
From: https://www.cnblogs.com/qdhys/p/17782223.html

相关文章

  • The 2021 CCPC Guilin Onsite (XXII Open Cup, Grand Prix of EDG)
    Preface昨天下午16:30~21:30刚打完CCPC2021的广州,今天早上九点又开始打这场桂林,压力拉满了属于是这场比起昨天那场良心太多了,开场还挺顺(虽然因为写Dijkstra偷懒TLE了四发),但开题啥的都是见一个会一个中期虽然有点卡但因为祁神会了几何所以没有空机,然后再点完外卖后我突然顿悟把BK......
  • The 2nd Universal Cup. Stage 5: Northern J Sets May Be Good
    题解我们考虑计算\(\sum_{S\subseteq\{1,2,3,\cdots,n\}}(-1)^{cnt(S)}\),这里\(cnt(S)\)表示\(S\)集合的导出子图的边数。我们记\(x_i=[i\inS]\)。我们考虑删掉\(n\)号点。注意到如果\(x_i\)的取值会影响\(cnt(s)\)的奇偶性,则正负相消,贡献为\(0\)。所以我们需......
  • ucup 题目乱炖
    Season2022#6299.BinaryString如果\(0\)的个数小于\(1\)的个数那么就反转\(01\)以及反转序列,接下来假设\(0\)的个数大于等于\(1\)的个数。称有\(11\)的序列为”未完全展开的“,那么序列的种类数有两个阶段:展开过程中和展开之后的。在展开之后如果知道序列那么用......
  • 【转载】关于使用CUPS共享打印机的正确姿势,你可以永远告别打印驱动了
    原文:https://www.right.com.cn/forum/thread-8276397-1-1.html 发表于2023-2-1715:42|只看该作者|只看大图本帖最后由kero990于2023-2-1715:48编辑一直以来,使用CUPS作为打印服务器是论坛里流行的做法,一方面这是windows的传统弱项,另一方面也是移动打印......
  • 在Ubuntu上用cups api实现打印功能
    https://blog.csdn.net/weixin_48885322/article/details/127270545在Ubuntu上用cupsapi实现打印功能银离子_kg已于2022-10-1310:00:47修改1768收藏5文章标签:ubuntulinuxbash版权​最近由于工作需要,要写一套打印相关的接口。Linux上一般自带一套管理打印机的通......
  • The 2nd Universal Cup. Stage 4: Taipei - I(状压DP)
    目录I.IntervalAdditionI.IntervalAddition题意给定一个长度为n$(1\len\le23)$的数组a。你可以进行一种操作:选择区间\([l,r]\)并给这个区间所有的数都加上一个任意的数。问你使得整个数组均为0所需的最小操作次数?思路考虑差分数组无论怎么对于区间\([l,r......
  • The 2018 ACM-ICPC Asia Qingdao Regional Contest, Online (The 2nd Universal Cup
    The2018ACM-ICPCAsiaQingdaoRegionalContest,Online(The2ndUniversalCup.Stage1:Qingdao)J-PresstheButton\(1\leqa,b,c,d\leq10^6\)题解容易发现存在循环节,每次位于\(gcd(a,c)\)的倍数的位置所以我们考虑处理一个循环节内的情况如果\(v\le......
  • Gym 104270 The 2018 ICPC Asia Qingdao Regional Programming Contest (The 1st Univ
    A.SequenceandSequenceB.KawaExam可以发现,对答案会产生影响的只有割边,把所有边双缩起来,然后就是一个森林。考虑一个树的时候怎么做,就是对于每条边求出这条边两端的众数个数,考虑线段树合并,每次动态维护子树内的众数和子树外的众数。#include<iostream>#include<cstdio>......
  • qoj6735. Tree (The 1st Universal Cup. Stage 22: Shaanxi)
    https://qoj.ac/contest/1287/problem/6735考虑定一个根,然后把每个点的点权附属在父边权上,让每条边的边权变成一个pair。这样,一个符合条件的路径需要满足的条件是:路径内所有边的边权pair相同,以及路径根节点(lca)的颜色符合。对于当前树上每个边权相同的连通块分开考虑。对......
  • CF957 Codeforces Round 472 (rated, Div. 2, based on VK Cup 2018 Round 2)
    CF957ATritonicIridescence如果原序列中有两个相同的字符,显然不合法。如果开头或者结尾为?,或者有两个连续的?,或者一个?两边的字符不同显然合法。否则一定不合法。#include<iostream>#include<cstdio>usingnamespacestd;constintN=105;intn;chars[N];intma......