Codeforces 1154E - Two Teams - [线段树+链表]
题目链接: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 - [线段树+链表]的更多相关文章
- Buses and People CodeForces 160E 三维偏序+线段树
Buses and People CodeForces 160E 三维偏序+线段树 题意 给定 N 个三元组 (a,b,c),现有 M 个询问,每个询问给定一个三元组 (a',b',c'),求满足 a ...
- CodeForces 877E DFS序+线段树
CodeForces 877E DFS序+线段树 题意 就是树上有n个点,然后每个点都有一盏灯,给出初始的状态,1表示亮,0表示不亮,然后有两种操作,第一种是get x,表示你需要输出x的子树和x本身 ...
- [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路)
[Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路) 题面 有n个空心物品,每个物品有外部体积\(out_i\)和内部体积\(in_i\),如果\(in_i& ...
- [Codeforces 1199D]Welfare State(线段树)
[Codeforces 1199D]Welfare State(线段树) 题面 给出一个长度为n的序列,有q次操作,操作有2种 1.单点修改,把\(a_x\)修改成y 2.区间修改,把序列中值< ...
- [Codeforces 316E3]Summer Homework(线段树+斐波那契数列)
[Codeforces 316E3]Summer Homework(线段树+斐波那契数列) 顺便安利一下这个博客,给了我很大启发(https://gaisaiyuno.github.io/) 题面 有 ...
- CF 552(div 3) E Two Teams 线段树,模拟链表
题目链接:http://codeforces.com/contest/1154/problem/E 题意:两个人轮流取最大值与旁边k个数,问最后这所有的数分别被谁给取走了 分析:看这道题一点思路都没有 ...
- Codeforces Gym 100231B Intervals 线段树+二分+贪心
Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...
- Codeforces 482B Interesting Array(线段树)
题目链接:Codeforces 482B Interesting Array 题目大意:给定一个长度为N的数组,如今有M个限制,每一个限制有l,r,q,表示从a[l]~a[r]取且后的数一定为q,问是 ...
- codeforces 383C Propagating tree 线段树
http://codeforces.com/problemset/problem/383/C 题目就是说, 给一棵树,将一个节点的值+val, 那么它的子节点都会-val, 子节点的子节点+val. ...
随机推荐
- mysql语句实战
请创建如下表,并创建相关约束 二.操作表 1.自行创建测试数据 2.查询“生物”课程比“物理”课程成绩高的所有学生的学号: 这个比较难, 3.查询平均成绩大于60分的同学的学号和平均成绩: 4.查 ...
- 51nod 1035 最长的循环节
正整数k的倒数1/k,写为10进制的小数如果为无限循环小数,则存在一个循环节,求<=n的数中,倒数循环节长度最长的那个数,假如存在多个最优的答案,输出所有答案中最大的那个数. 1/6= 0.1( ...
- PLSQL安装、PLSQL汉化、激活
前言 新版PLSQL连接Oracle时,不需要Oracle客户端为32位了,安装完Oracle后也不需要在单独安装客户端. 一.准备工作 1.点击下载PLSQL,本次安装的PLSQL版本为12.0.7 ...
- 【全网最全的博客美化系列教程】08.自定义地址栏Logo
全网最全的博客美化系列教程相关文章目录 [全网最全的博客美化系列教程]01.添加Github项目链接 [全网最全的博客美化系列教程]02.添加QQ交谈链接 [全网最全的博客美化系列教程]03.给博客添 ...
- bootstrap 解决弹出窗口(modal) 常见问题
无法使用键盘esc关闭窗口方法: 首先在modal容器的div中增加属性tabindex="-1",其次设置键盘ESC属性keyboard为true: 方法1:使用js打开窗口时 ...
- 【原创】大数据基础之Ambari(1)简介、编译安装、使用
官方:http://ambari.apache.org/ The Apache Ambari project is aimed at making Hadoop management simpler ...
- [Linux]权限s权限和t权限
问题 在<Unix高级编程>第4.9章节中描述了函数chmod()的参数mode常量值 当中S_ISUID.S_ISGID.S_ISVTX三个常量让人困惑. 分析 通过查阅文档,发现这几个 ...
- 如何给PDF文档添加和删除贝茨编号
PDF文件的使用频率高了,我们也不只局限于使用PDF文件了,也会需要编辑PDF文件的时候,那么如何在PDF文件中添加和去除贝茨编号呢,应该有很多小伙伴都想知道吧,今天就来跟大家分享一下吧,小伙伴们就一 ...
- Main Thread Checker 问题解决
1. without a return value https://developer.apple.com/documentation/code_diagnostics/main_thread_che ...
- python开发环境搭建及numpy基本属性-【老鱼学numpy】
目的 本节我们将介绍如何搭建python的开发环境以及numpy的基本属性,这样可以检验我们的numpy是否安装正确了. python开发环境的搭建 工欲善其事必先利其器,我用得比较顺手的是Intel ...