NOIP 模拟 $20\; \rm z$
题解
很考验思维的一道题
对于不同的任务点,发现如果 \(x_{i-1}<x_i<x_{i+1}\) 或 \(x_{i-1}>x_i>x_{i+1}\) 那么 \(x_i\) 这个位置的数就没用了
将序列先扫一遍,合并不同的位置,然后将合并后的 \(x_i->x_{i+1}\) 按距离排序,再将询问序列从小到大排序,离线询问
用一个 \(map\) 存储所有 \(x_{i}->x_{i+1}\) 的任务编号,二分查找当前点
那么当一个长度大于这段区间了,它就会超出范围,要将它左右的区间和它合并
注意:ans[c[t].id]=calc(ans[c[t].l),t++
不能写成 ans[c[t].id]=calc(ans[c[t++].l)
,因为在高版本 c++ 中是从右往左编译的
Code
#include<bits/stdc++.h>
#define ri register signed
#define p(i) ++i
using namespace std;
namespace IO{
char buf[1<<21],*p1=buf,*p2=buf;
#define gc() p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++
template<typename T>inline void read(T &x) {
ri f=1;x=0;register char ch=gc();
while(ch<'0'||ch>'9') {if (ch=='-') f=0;ch=gc();}
while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=gc();}
x=f?x:-x;
}
}
using IO::read;
namespace nanfeng{
#define node(id,x) (node){id,x}
#define FI FILE *IN
#define FO FILE *OUT
template<typename T>inline T cmax(T x,T y) {return x>y?x:y;}
template<typename T>inline T cmin(T x,T y) {return x>y?y:x;}
typedef long long ll;
static const int N=1e5+7;
struct node{int id;ll x;}al[N];
inline int operator<(const node &n1,const node &n2) {return n1.x>n2.x;}
inline int cmp(node n1,node n2) {return n1.x<n2.x;}
priority_queue<node> que;
map<int,int> mp;
int n,q,cnt,t=1;
ll sum,dx[N],ans[N];
inline ll calc(ll l) {
if (mp.empty()) return 0;
if (mp.begin()->second<0) return sum-(mp.size()-1)*l;
return sum-mp.size()*l;
}
inline int main() {
// FI=freopen("nanfeng.in","r",stdin);
// FO=freopen("nanfeng.out","w",stdout);
read(n),read(q);
ri lst=0;
for (ri i(1),x;i<=n;p(i)) {
read(x);
if (x==lst) continue;
if (cnt&&(dx[cnt]<0&&x-lst<0||dx[cnt]>0&&x-lst>0)) dx[cnt]+=x-lst;
else dx[p(cnt)]=x-lst;
lst=x;
}
for (ri i(1),l;i<=q;p(i)) read(l),al[i].x=l,al[i].id=i;
sort(al+1,al+q+1,cmp);
for (ri i(1);i<=cnt;p(i)) {
sum+=abs(dx[i]);
mp[i]=dx[i];
que.push(node(i,abs(dx[i])));
}
while(!que.empty()) {
node tmp=que.top();que.pop();
auto it=mp.lower_bound(tmp.id);
if (it==mp.end()) continue;
node nw=node(it->first,it->second);
if (abs(nw.x)!=tmp.x||nw.id!=tmp.id) continue;
while(t<=q&&tmp.x>al[t].x) ans[al[t].id]=calc(al[t++].x);
auto bg=mp.begin();
if (it!=mp.begin()) {
if (it!=prev(mp.end())) {
auto pr=prev(it),nx=next(it);
node tmpr=node(pr->first,pr->second);
node tmpn=node(nx->first,nx->second);
mp.erase(pr);mp.erase(nx);
sum-=abs(nw.x);
sum-=abs(tmpr.x);
sum-=abs(tmpn.x);
tmp.x=nw.x;
tmp.x+=tmpr.x;
tmp.x+=tmpn.x;
it->second=tmp.x;
tmp.x=abs(tmp.x);
sum+=tmp.x;
que.push(tmp);
} else {
sum-=abs(nw.x);
mp.erase(it);
}
} else {
if (nw.x>0) {
if (it!=prev(mp.end())) {
auto nx=next(it);
node tmpn=node(nx->first,nx->second);
mp.erase(nx);
sum-=abs(nw.x);
sum-=abs(tmpn.x);
tmp.x=nw.x;
tmp.x+=tmpn.x;
if (tmp.x) {
it->second=tmp.x;
tmp.x=abs(tmp.x);
sum+=tmp.x;
que.push(tmp);
} else mp.erase(it);
} else {
sum-=abs(tmp.x);
mp.erase(it);
}
}
}
}
while(t<=q) ans[al[t].id]=calc(al[t++].x);
for (ri i(1);i<=q;p(i)) printf("%lld\n",ans[i]);
return 0;
}
}
int main() {return nanfeng::main();}
NOIP 模拟 $20\; \rm z$的更多相关文章
- NOIP 模拟 $20\; \rm y$
题解 \(by\;zj\varphi\) 首先发现一共最多只有 \(2^d\) 种道路,那么可以状压,(不要 \(dfs\),会搜索过多无用的状态) 那么设 \(f_{i,j,k}\) 为走 \(i\ ...
- NOIP 模拟 $20\; \rm 玩具$
题解 \(by\;zj\varphi\) 一道概率与期望好题 对于一棵树,去掉根后所有子树就是一个森林,同理,一个森林加一个根就是一棵树 设 \(f_{i,j}\) 为有 \(i\) 个点的树,高度为 ...
- 7.22 NOIP模拟7
又是炸掉的一次考试 T1.方程的解 本次考试最容易骗分的一道题,但是由于T2花的时间太多,我竟然连a+b=c都没判..暴力掉了40分. 首先a+b=c,只有一组解. 然后是a=1,b=1,答案是c-1 ...
- NOIP模拟 1
NOIP模拟1,到现在时间已经比较长了.. 那天是6.14,今天7.18了 //然鹅我看着最前边缺失的模拟1,还是终于忍不住把它补上,为了保持顺序2345重新发布了一遍.. # 用 户 名 ...
- 20190725 NOIP模拟8
今天起来就是虚的一批,然后7.15开始考试,整个前半个小时异常的困,然后一看题,T1一眼就看出了是KMP,但是完了,自己KMP的打法忘的一干二净,然后开始打T2,T2肝了一个tarjan点双就扔上去了 ...
- 20190902+0903合集-NOIP模拟
一直没时间写QwQ 于是补一下. Day 1 晚饭吃的有点恶心…… $1s\,2s\,5s$ 还开 -O2 ?? 有点恐怖. T1 猛的一想: 把外面设成一个点, 向入口连一条权为排队时间的边 从出口 ...
- 2021.5.22 noip模拟1
这场考试考得很烂 连暴力都没打好 只拿了25分,,,,,,,,好好总结 T1序列 A. 序列 题目描述 HZ每周一都要举行升旗仪式,国旗班会站成一整列整齐的向前行进. 郭神作为摄像师想要选取其中一段照 ...
- NOIP 模拟 $16\; \rm Lost My Music$
题解 \(by\;zj\varphi\) 一道凸包的题 设 \(\rm dep_u\) 表示节点 \(u\) 的深度,那么原式就可化为 \(-\frac{c_v-c_u}{dep_v-dep_u}\) ...
- 道路 [NOIP模拟]
Description 我们看见了一个由 m 行 n 列的 1*1 的格子组成的矩阵,每个格子(I,j)有对应的高度 h[i][j]和初始的一个非负权值 v[i][j].我们可以随便选择一个格子作为起 ...
随机推荐
- cut和grep 选取命令
cut命令 cut:将一段信息的某一段"切"出来,处理的信息是以行为单位.参数: -d :后接分隔字符,与-f一起使用: -f :依据-d的分隔字符将一段信息切割成为数段,用-f取 ...
- C语言:清空缓冲区
缓冲区的优点很明显,它加快了程序的运行速度,减少了硬件的读写次数,让整个计算机变得流畅起来:但是,缓冲区也带来了一些负面影响,经过前面几节的学习相信读者也见识到了.那么,该如何消除这些负面影响呢?思路 ...
- 如何热更新长缓存的 HTTP 资源
前言 HTTP 缓存时间一直让开发者头疼.时间太短,性能不够好:时间太长,更新不及时.当遇到严重问题需紧急修复时,尽管后端文件可快速替换,但前端文件仍从本地缓存加载,导致更新长时间无法生效. 对于这个 ...
- SpringBoot自动装配-自定义Start
SpringBoot自动装配 在没有使用SpringBoot之前,使用ssm时配置redis需要在XML中配置端口号,地址,账号密码,连接池等等,而使用了SpringBoot后只需要在applicat ...
- Python Unittest简明教程
1 概述 单元测试框架是一种软件测试方法,通过来测试源代码中的各个单元,例如类,方法等,以确定它们是否符合要求.直观上来说,可以将单元视为最小的可测试部分.单元测试是程序员在开发过程中创建的短代码片段 ...
- 在Windows7/8/10 64位操作系统下安装并注册ocx控件
例如: 先网上下载一个MtbLine.ocx控件放入C:\Windows\SysWOW64\目录下 1.首先确保你的 Windows7 账户是管理员权限 2.下载MtbLine.ocx控件,网上可搜到 ...
- Sunset靶机
仅供个人娱乐 靶机信息 https://www.vulnhub.com/entry/sunset-sunrise,406/ 一.主机探测 二.信息收集 nmap -sS -sV -T5 -A -p- ...
- Excel VBA活动抽奖小程序
在活动中,我们常会有抽奖,抽奖箱准备繁琐,现在多采用线上抽奖方式,下面用Excel VBA写了一个简单的抽奖小程序 简单测试效果如下,可实现: 多次抽奖,且每次抽奖都不重复 抽奖界面滚动人员信息,点击 ...
- 干了六年Android开发现在裸辞失业了,再过2个月就30了,该怎么继续生活?
这是我在某论坛看到别人分享的故事,觉得可以展开聊一下,对于我们这些中年程序员,可以裸辞吗? 前言 首先介绍一下主人公的情况.目前所在的是一家小的创业公司,待了3年多,薪资一般吧,之前在一家中型上市企业 ...
- 七夕特别篇|用Python绘画牛郎织女在鹊桥相见
大家好,我是辰哥~ 今天就是七夕节,首先提前祝福有伴侣的小伙伴,七夕快乐,没有伴侣的小伙伴,今天就会找到伴侣,(给看到这句话的你好运加持,哈哈哈). 作为会Python的我们必须做点好玩且有意义的东西 ...