E. Two Teams(双向链表模拟)

52 篇文章 1 订阅

https://codeforces.com/problemset/problem/1154/E


 

题目描述

There are nn students standing in a row. Two coaches are forming two teams — the first coach chooses the first team and the second coach chooses the second team.

The ii -th student has integer programming skill a_iai​ . All programming skills are distinct and between 11 and nn , inclusive.

Firstly, the first coach will choose the student with maximum programming skill among all students not taken into any team, and kk closest students to the left of him and kk closest students to the right of him (if there are less than kk students to the left or to the right, all of them will be chosen). All students that are chosen leave the row and join the first team. Secondly, the second coach will make the same move (but all students chosen by him join the second team). Then again the first coach will make such move, and so on. This repeats until the row becomes empty (i. e. the process ends when each student becomes to some team).

Your problem is to determine which students will be taken into the first team and which students will be taken into the second team.

输入格式

The first line of the input contains two integers nn and kk ( 1 \le k \le n \le 2 \cdot 10^51≤k≤n≤2⋅105 ) — the number of students and the value determining the range of chosen students during each move, respectively.

The second line of the input contains nn integers a_1, a_2, \dots, a_na1​,a2​,…,an​ ( 1 \le a_i \le n1≤ai​≤n ), where a_iai​ is the programming skill of the ii -th student. It is guaranteed that all programming skills are distinct.

输出格式

Print a string of nn characters; ii -th character should be 1 if ii -th student joins the first team, or 2 otherwise.

题意翻译

Description

有 nn 个人站成一排,他们每个人都有一个能力值,能力值互不相同。

有两个教练,分别是 11 队教练和 22 队教练。由 11 队教练先挑,每次教练会将场上剩下的人中能力值最高的和他左右各 kk 个人从场上挑出,加入自己的队伍,然后由另一名教练再挑。

在挑选时如果一侧不足 kk 个人则将这些人都挑入队伍。

请求出每个人最终加入的是哪个队伍

Input

第一行是两个整数 n,~kn, k

下面一行是一个 11 到 nn 的排列,描述每个人的能力值

Output

输出一行一个字符串。如果第 ii 个人最终加入 11 队,则字符串第 ii 位为 11,否则为 22。

Limitation

1~\leq~k~\leq~n~\leq~2~\times~10^51 ≤ k ≤ n ≤ 2 × 105

Translated By @ 一扶苏一

输入输出样例

输入 #1复制

5 2
2 4 5 3 1

输出 #1复制

11111

输入 #2复制

5 1
2 1 3 5 4

输出 #2复制

22111

输入 #3复制

7 1
7 2 1 3 5 4 6

输出 #3复制

1121122

输入 #4复制

5 1
2 4 5 3 1

输出 #4复制

21112

思路:开始暴力想法是O(n)找到队里最大的,然后左扫右扫标记。

用双向链表优化。拿一个结构体记录值和下标然后根据值sort,sort完后从最大值去看是否被访问,未访问就通过双向链表的关系O(1)找下标标记同时更新下标相连关系。均摊O(n)复杂度

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=2e5+100;
typedef long long LL;
LL n,k,vis[maxn];
LL pre[maxn],nxt[maxn];
struct node{
	LL val,id;
}a[maxn];
bool cmp(node A,node B)
{
	return A.val>B.val;
}
void solve()
{
	for(LL i=1;i<=n;i++){
		cin>>a[i].val;a[i].id=i;
	}
	for(LL i=1;i<=n;i++){
		pre[i]=i-1;
		nxt[i]=i+1;
	}
	sort(a+1,a+1+n,cmp);
	LL flag=1;
	for(LL i=1;i<=n;i++)
	{
		if(!vis[a[i].id]){
			LL pos=a[i].id;
			LL js=k+1;//往前扩展 
			while(js&&!vis[pos]&&pos>=1)
			{
				vis[pos]=flag;
				js--;
				pos=pre[pos];
			}
			LL st=pos;//扩展到的前面的点 
			js=k;
			pos=nxt[a[i].id];
			while(js&&!vis[pos]&&pos<=n)
			{
				vis[pos]=flag;
				js--;
				pos=nxt[pos];
			}
			pre[pos]=st;
			nxt[st]=pos;
			if(flag==1) flag=2;
			else if(flag==2)flag=1;
		}	
	}
	for(LL i=1;i<=n;i++){
		cout<<vis[i];
	}
	cout<<endl;
}
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  cin>>n>>k;
  solve();
return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值