题目链接:https://codeforces.com/contest/1154/problem/E

题意:

$n$ 个人排成一排,第 $i$ 个人的能力值为 $a[i]$,$a[1 \sim n]$ 是 $1 \sim n$ 的某个排列。

第一个教练先来拉人,他会拉目前还在队伍中的 $a[i]$ 最高的那个人,并且把排在它前面和后面的各自 $k$ 个人都拉走,即最多可以拉走 $2k + 1$ 个人。

然后,第二个教练来拉人,也是同样的操作。注意,如果当前被拉走的人的前面或者后面不足 $k$ 个人,那就尽可能多地拉人。

两个教练轮流拉人,直到整个队伍中一个人都不剩。要求你给出最后每个人被哪个教练拉走了。

题解:

老年手速选手,时间紧没写完……

一开始先考虑直接用一个线段树搞定,发现有点难……而且时间复杂度也不一定能过。

后来,考虑加入一个链表来维护目前的这一排队伍。

我们用线段树维护这 $n$ 个人的能力值;可以做到对整个区间求最大值,也就能知道目前队伍里哪个人是能力值最大的;其次用线段树做区间修改,可以把被拉走的人的能力值设为 $0$。

然后,对于被拉走的那个人,我们在链表上分别往前、往后移动指针 $k$ 次,就能得到需要删去的那一段链,直接 $O(1)$ 删除。同时在指针移动时顺便把每个人标记好他们是被哪个教练拉走的。

这样一来,时间复杂度为 $O(\frac{n}{k} \log n + n)$。

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+; int n,k,a[maxn];
int pos[maxn];
int head,tail,pre[maxn],nxt[maxn];
int ans[maxn]; #define ls (rt<<1)
#define rs (rt<<1|1)
struct Node
{
int l,r;
int val;
bool lazy;
void update()
{
val=;
lazy=;
}
}o[maxn<<];
void pushdown(int rt)
{
if(o[rt].lazy)
{
o[ls].update();
o[rs].update();
o[rt].lazy=;
}
}
void pushup(int rt)
{
o[rt].val=max(o[ls].val,o[rs].val);
}
void build(int rt,int l,int r)
{
o[rt].l=l, o[rt].r=r;
o[rt].lazy=;
if(l==r)
{
o[rt].val=a[l];
return;
}
int mid=(l+r)>>;
build(ls,l,mid);
build(rs,mid+,r);
pushup(rt);
}
void update(int rt,int st,int ed)
{
if(st<=o[rt].l && o[rt].r<=ed)
{
o[rt].update();
return;
}
pushdown(rt);
int mid=(o[rt].l+o[rt].r)>>;
if(st<=mid) update(ls,st,ed);
if(mid<ed) update(rs,st,ed);
pushup(rt);
}
int query(int rt,int st,int ed)
{
if(st<=o[rt].l && o[rt].r<=ed) return o[rt].val;
pushdown(rt);
int mid=(o[rt].l+o[rt].r)>>;
int res=;
if(st<=mid) res=max(res,query(ls,st,ed));
if(mid<ed) res=max(res,query(rs,st,ed));
pushup(rt);
return res;
} int main()
{
cin>>n>>k;
nxt[head=]=, pre[tail=n+]=n;
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
pos[a[i]]=i;
pre[i]=i-, nxt[i]=i+;
} build(,,n);
bool team=;
while()
{
int mx=query(,,n);
if(mx<=) break; ans[pos[mx]]=team;
int l=pos[mx], r=pos[mx];
for(int i=;i<=k;i++)
{
if(pre[l]==head) break;
else l=pre[l], ans[l]=team;
}
for(int i=;i<=k;i++)
{
if(nxt[r]==tail) break;
else r=nxt[r], ans[r]=team;
}
update(,l,r);
int pre_l=pre[l], nxt_r=nxt[r];
nxt[pre_l]=nxt_r, pre[nxt_r]=pre_l; team^=;
} for(int i=;i<=n;i++) printf("%d",ans[i]+);
}

Codeforces 1154E - Two Teams - [线段树+链表]的更多相关文章

  1. Buses and People CodeForces 160E 三维偏序+线段树

    Buses and People CodeForces 160E 三维偏序+线段树 题意 给定 N 个三元组 (a,b,c),现有 M 个询问,每个询问给定一个三元组 (a',b',c'),求满足 a ...

  2. CodeForces 877E DFS序+线段树

    CodeForces 877E DFS序+线段树 题意 就是树上有n个点,然后每个点都有一盏灯,给出初始的状态,1表示亮,0表示不亮,然后有两种操作,第一种是get x,表示你需要输出x的子树和x本身 ...

  3. [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路)

    [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路) 题面 有n个空心物品,每个物品有外部体积\(out_i\)和内部体积\(in_i\),如果\(in_i& ...

  4. [Codeforces 1199D]Welfare State(线段树)

    [Codeforces 1199D]Welfare State(线段树) 题面 给出一个长度为n的序列,有q次操作,操作有2种 1.单点修改,把\(a_x\)修改成y 2.区间修改,把序列中值< ...

  5. [Codeforces 316E3]Summer Homework(线段树+斐波那契数列)

    [Codeforces 316E3]Summer Homework(线段树+斐波那契数列) 顺便安利一下这个博客,给了我很大启发(https://gaisaiyuno.github.io/) 题面 有 ...

  6. CF 552(div 3) E Two Teams 线段树,模拟链表

    题目链接:http://codeforces.com/contest/1154/problem/E 题意:两个人轮流取最大值与旁边k个数,问最后这所有的数分别被谁给取走了 分析:看这道题一点思路都没有 ...

  7. Codeforces Gym 100231B Intervals 线段树+二分+贪心

    Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...

  8. Codeforces 482B Interesting Array(线段树)

    题目链接:Codeforces 482B Interesting Array 题目大意:给定一个长度为N的数组,如今有M个限制,每一个限制有l,r,q,表示从a[l]~a[r]取且后的数一定为q,问是 ...

  9. codeforces 383C Propagating tree 线段树

    http://codeforces.com/problemset/problem/383/C 题目就是说,  给一棵树,将一个节点的值+val, 那么它的子节点都会-val, 子节点的子节点+val. ...

随机推荐

  1. Rich feature hierarchies for accurate object detection and semantic segmentation(理解)

    0 - 背景 该论文是2014年CVPR的经典论文,其提出的模型称为R-CNN(Regions with Convolutional Neural Network Features),曾经是物体检测领 ...

  2. Vue实战笔记

    1.组件的属性 例子: <template> <div class="hello"> <test-props name="demo" ...

  3. HDU 2196 Compute --树形dp

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  4. OpenCV imread读取jpg图像的一个大坑

    长话短说 版本区间[OpenCV3.0.0, OpenCV3.4.1]内的OpenCV,(至少在windows下,使用官方提供的预编译版本),imread读取jpg图片后的像素值,和版本区间[Open ...

  5. MySQL和B树的那些事

    一.零铺垫 在介绍B树之前,先来看另一棵神奇的树——二叉排序树(Binary Sort Tree),首先它是一棵树,“二叉”这个描述已经很明显了,就是树上的一根树枝开两个叉,于是递归下来就是二叉树了( ...

  6. PHP二维数组按某个字段排序

    //准备 二维数组 //按一个字段排序 foreach($rank as $key=>$val){ $dos[$key] = $val['timelength']; } array_multis ...

  7. Hadoop生态组件Hive,Sqoop安装及Sqoop从HDFS/hive抽取数据到关系型数据库Mysql

    一般Hive依赖关系型数据库Mysql,故先安装Mysql $: yum install mysql-server mysql-client [yum安装] $: /etc/init.d/mysqld ...

  8. 原子动作检测 A Better Baseline for AVA

    本文将Faster-RCNN用在了I3D的feature map上,用于视频中多人多动作的检测 challege比赛第二名的整体方法是将Faster-RCNN作用在I3Dfeature上.训练时,以标 ...

  9. mysql中的数据类型enum和set

    mysql中的字符串数据类型set,enum 原文网址: https://www.cnblogs.com/benbenzhu/p/5604598.html 1.enum 单选字符串数据类型,适合存储表 ...

  10. CoopyIII开发文档之控制LED灯开关

    作者:那年:QQ:843681152 一. CooplyIII环境的搭建 工欲善其事必先利器,如何搭建CooplyIII的开发环境是一切coolpyIII开发的前提.CoolpyIII作者内cool超 ...