计蒜客模拟赛5 D2T2 蚂蚁搬家
很久很久以前,有很多蚂蚁部落共同生活在一片祥和的村庄里。但在某一天,村庄里突然出现了一只食蚁兽,蚂蚁们为了保全性命而决定搬家。
然而这个村庄四面环山,想要离开这个村庄必须要从地洞里离开,村子里一共有 2n2n2n 个地洞,分布在山的左右,一边 nnn 个。左边的任意一个地洞都可以通到右边 nnn 个地洞中的任意的一个,如图所示(两侧地洞从上至下编号为 111 到 nnn)。
对于右边的第 iii 个出口,附近有数量为 wiw_iwi 的食物。
现在前后依次来了 qqq 个蚂蚁部落,第 iii 个部落有 aia_iai 只蚂蚁,它们会从左边第 bib_ibi 个地洞离开,并且选择一个右侧的出口,出口的食物必须大于等于 aia_iai,如果有多个满足要求的出口,则选择距离 bib_ibi 最近的(假设蚂蚁从右边的编号为 kkk 的地洞出来,那么距离定义为 ∣k−bi∣|k-b_i|∣k−bi∣)。如果有多个洞口符合要求,选择编号最小的出口离开,并且占据这个出口数量为 aia_iai 的食物,当前洞口的食物数量减少 aia_iai。
请输出每群蚂蚁会选择哪个出口,如果没有符合要求的出口,输出 −1-1−1,并且忽略这群蚂蚁。
输入格式
第一行两个整数 nnn 和 qqq。
接下来 nnn 行,每行一个整数 wiw_iwi,表示右方第 iii 个洞口的食物数量。
接下来 qqq 行,每行两个整数 aia_iai 和 bib_ibi,表示蚂蚁数量和它们离开的洞口。
输出格式
一共 qqq 行,每行一个整数,表示第 iii 群蚂蚁会选择哪个出口。
数据规模
对于 30%30\%30% 的数据:n,q≤3000n,q \le 3000n,q≤3000。
对于 60%60\%60% 的数据:n,q≤100000n,q \le 100000n,q≤100000。
对于另外 20%20\%20% 的数据保证:ai=1a_i=1ai=1。
对于 100%100\%100% 的数据:n,q≤500000n,q \le 500000n,q≤500000,ai,wi≤109a_i,w_i \le 10^9ai,wi≤109,bi≤nb_i \le nbi≤n。
更多样例
样例解释
原始的剩余食物为 9,8,6,10,59,8,6,10,59,8,6,10,5。
查询 4,54,54,5,选择第 555 个洞口出来,剩下食物为 9,8,6,10,19,8,6,10,19,8,6,10,1。
查询 2,52,52,5,选择第 444 个洞口出来,剩下食物为 9,8,6,8,19,8,6,8,19,8,6,8,1。
查询 8,18,18,1,选择第 111 个洞口出来,剩下食物为 1,8,6,8,11,8,6,8,11,8,6,8,1。
查询 9,39,39,3,这时候没有满足条件的洞口了,忽略之。
查询 3,13,13,1,选择第 222 个洞口出来,剩下食物为 1,5,6,8,11,5,6,8,11,5,6,8,1。
忽略每行输出的末尾多余空格
样例输入
5 5
9 8 6 10 5
4 5
2 5
8 1
9 3
3 1
样例输出
5
4
1
-1
2
对于30%的数据:n≤300直接暴力找就好 对于60%的数据:题目要求相当于找距离bi最近的且大于等于ai的位置
这个可以用二分位置+线段树求区间min实现
复杂度 O(n lg n)
如果没有nb的卡常技巧大概是过不了100分的 对于另外20%的数据:ai =1
相当于找距离i最近的值≥1的点,我们考虑线段树之外的做法
维护两个并查集,分别指向当前点往上第一个不为0的点和往下第一个不为0的点。
复杂度O(nlgn) 。 对于 100% 的数据:
依然考虑用线段树维护,假设现在要找编号小于i的距离i最近的点
我们记录一个数组pos[i]表示代表位置i的线段树的叶子节点的编号,然后从这个节点往上找
如果当前点是fa的左儿子,什么也不做,然后向fa走一步
如果当前点是fa的右儿子,如果fa的左儿子中的最大值≥a[i],那么递归在fa的左儿子中找答案,现
在区间是一整个节点,就可以利用线段树的二分结构往下找。
否则什么也不做,然后向fa走一步。
向右同理
复杂度O(nlgn)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int inf=2e9;
int n,q,w[],c[],L[],R[],pos[];
void pushup(int rt)
{
c[rt]=max(c[rt*],c[rt*+]);
}
void build(int rt,int l,int r)
{
L[rt]=l;R[rt]=r;
if (l==r)
{
c[rt]=w[l];
pos[l]=rt;
return;
}
int mid=(l+r)/;
build(rt*,l,mid);
build(rt*+,mid+,r);
pushup(rt);
}
void update(int rt,int l,int r,int x,int d)
{
if (l==r)
{
c[rt]+=d;
return;
}
int mid=(l+r)/;
if (x<=mid) update(rt*,l,mid,x,d);
else update(rt*+,mid+,r,x,d);
pushup(rt);
}
int take1(int rt,int x)
{
if (L[rt]==R[rt]) return L[rt];
if (c[rt*+]>=x) return take1(rt*+,x);
return take1(rt*,x);
}
int take2(int rt,int x)
{
if (L[rt]==R[rt]) return L[rt];
if (c[rt*]>=x) return take2(rt*,x);
return take2(rt*+,x);
}
int find1(int rt,int x)
{
if (rt==) return inf;
if (rt&)
if (c[rt-]>=x) return take1(rt-,x);
return find1(rt/,x);
}
int find2(int rt,int x)
{
if (rt==) return inf;
if ((rt&)==)
if (c[rt+]>=x) return take2(rt+,x);
return find2(rt/,x);
}
int main()
{int i,x,y,p1,p2;
cin>>n>>q;
for (i=;i<=n;i++)
{
scanf("%d",&w[i]);
}
build(,,n);
while (q--)
{
scanf("%d%d",&x,&y);
if (w[y]>=x) p1=p2=y;
else p1=find1(pos[y],x),p2=find2(pos[y],x);
if (p1==inf&&p2==inf) printf("-1\n");
else
{
if (abs(y-p1)<=abs(p2-y))
{
printf("%d\n",p1);
w[p1]-=x;
update(,,n,p1,-x);
}
else
{
printf("%d\n",p2);
w[p2]-=x;
update(,,n,p2,-x);
}
}
}
}
计蒜客模拟赛5 D2T2 蚂蚁搬家的更多相关文章
- 计蒜客模拟赛5 D2T1 成绩统计
又到了一年一度的新生入学季了,清华和北大的计算机系同学都参加了同一场开学考试(因为两校兄弟情谊深厚嘛,来一场联考还是很正常的). 不幸的是,正当老师要统计大家的成绩时,世界上的所有计算机全部瘫痪了. ...
- 计蒜客模拟赛D2T2 蒜头君的排序:区间逆序对(移动端点) + 树状数组
题目链接:https://nanti.jisuanke.com/t/16443 题意: 给你一个由1~n构成的正整数序列,有m组询问,每组询问要求输出[l , r]区间内的逆序对个数. 数据范围: 对 ...
- 计蒜客模拟赛D2T3 蒜头君救人:用bfs转移状压dp
题目链接:https://nanti.jisuanke.com/t/16444 题意: 蒜头君是一个乐于助人的好孩子,这天他所在的乡村发生了洪水,有多名村民被困于孤岛上,于是蒜头君决定去背他们离开困境 ...
- 计蒜客模拟赛D1T3 蒜头君的坐骑:用dfs转移dp
题目链接:https://nanti.jisuanke.com/t/16447 题意: 蒜头君有一只坐骑,人马. 一天,蒜头君骑着他的坐骑走上了一片n*m的大荒野,一开始时,蒜头君在(1,1)点,他要 ...
- 计蒜客模拟赛D2T1 蒜头君的兔子:矩阵快速幂
题目链接:https://nanti.jisuanke.com/t/16442 题意: 有个人在第一年送了你一对1岁的兔子.这种兔子刚生下来的时候算0岁,当它在2~10岁的时候,每年都会生下一对兔子, ...
- 计蒜客模拟赛D1T2 蒜头君的树:树上节点之间最短距离和
题目链接:https://nanti.jisuanke.com/t/16446 题意: 给你一棵有n个节点的树以及每条边的长度,输出树上节点之间的最短距离和.然后进行m次操作,每次操作更改一条边的长度 ...
- 计蒜客模拟赛D1T1 蒜头君打地鼠:矩阵旋转+二维前缀和
题目链接:https://nanti.jisuanke.com/t/16445 题意: 给你一个n*n大小的01矩阵,和一个k*k大小的锤子,锤子只能斜着砸,问只砸一次最多能砸到多少个1. 题解: 将 ...
- 计蒜客模拟赛 #5 (B 题) 动态点分治+线段树
虽然是裸的换根dp,但是为了在联赛前锻炼码力,强行上了点分树+线段树. 写完+调完总共花了不到 $50$ 分钟,感觉还行. code: #include <bits/stdc++.h> # ...
- 2019ICPC西安邀请赛(计蒜客复现赛)总结
开始时因为吃饭晚了一刻钟,然后打开比赛.看了眼榜单A题已经过了二十来个队伍了,宝儿就去做A. 传师说最后一题看题目像最短路,于是我就去看M了,宝儿做完之后也来陪我看.M一开始看到时以为是像 POJ ...
随机推荐
- 记录python接口自动化测试--从excel中读取params参数传入requests请求不生效问题的解决过程(第七目)
在第六目把主函数写好了,先来运行一下主函数 从截图中可以看到,请求参数打印出来了,和excel中填写的一致 但是每个接口的返回值却都是400,提示参数没有传进去,开始不知道是什么原因(因为excel中 ...
- 结合jenkins在Linux服务器搭建测试环境
何时使用: 测试过程中我们需要持续构建一个软件项目,为避免重复的手动下载.解压操作,我们需要搭建一个能够自动构建的测试环境,当代码有更新时,测试人员只需点一下[构建]即可拉取最新的代码进行测试(也可设 ...
- alpha冲刺第八天
一.合照 二.项目燃尽图 三.项目进展 首页文章显示部分 首页小功能福大地图完成 四.明日规划 发现爬取的数据是一整个网页的内容,而我们需要的仅仅是教务处通知的文章,在筛选方面还需要改进,查找如何进行 ...
- Beta冲刺 第二天
Beta冲刺 第二天 1. 昨天的困难 由于前面的冲刺留下的问题很多,而且混乱的代码给我们接下来的完善工作带来了巨大的困难. 2. 今天解决的进度 潘伟靖: 1.对代码进行了review 2.为系统增 ...
- 201621123031 《Java程序设计》第6周学习总结
作业06-接口.内部类 1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图或相关笔记,对面向对象思想进行一个总结. 注1:关键词与内容不求多 ...
- 04_Linux目录文件操作命令1(mv ls cd...)_我的Linux之路
上一节已经给大家讲了Linux的目录结构,相信大家已经对Linux的整个目录结构有所了解 现实中,服务器(包含Linux,Unix,windows server)一般都摆放在机房里,因为一个机房摆放了 ...
- Python-socket网络编程-Day8
目录Day8-Python socket 11.Socket 11.1.socket和file的区别: 11.2.WEB服务应用: 21.3.更多功能 21.4.socket方法: 41.5. 服务端 ...
- istio入门(01)istio的优势在哪里?
Istio能做什么?Istio 试图解决微服务实施后面临的问题.Istio 提供了一个完整的解决方案,对整个服务网格行为洞察和操作控制,以满足微服务应用程序的多样化需求. Istio在服务网络中提供了 ...
- C#微信公众号——自定义菜单
自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单.一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“...”代替.自定义菜单的介绍,可以看官方开发文档http://mp. ...
- golang-在gin中cookie跨域设置(配合ajax)
1.当我在golang中,在前后端分离的情况下使用cookies时发现,跨域没有被允许.代码如下: func AccessJsMiddleware() gin.HandlerFunc { return ...