[NOIP10.4模拟赛]3.z题解--思维
题目链接:
咕咕
闲扯:
哈哈这道T3考场上又敲了5个namespace,300+行,有了前车之鉴还对拍过,本以为子任务分稳了
结果只有30分哈哈,明明用极限数据对拍过不知怎么回事最后数据又是读不全,玄学,要是NOIP这样就GG了
首先第一个子任务贪心模拟即可,但是第二个子任务就像NOID1T1,你啥也不能输出但是我输出了0哈哈,真的是傻到家了,第三个子任务简单考虑一下即可;第四个子任务已经想到了偏正解的做法,但是用了个很SB的方法维护,昨天的T3也是这样但是都GG了...感觉退役钦定了
感谢WYT大佬正解讲解,高一神仙tql
分析:
先考虑第四个子任务,我说一下我在考场上的做法,我们设\(pos[i]\)是第i个任务的坐标,同时先将区间长度排序离线处理
先考虑pos[1]>0的情况,我们把相邻正负两点看成一对处理,所以我们可以一开始在负的点值那里加一个0点这样就凑成对了,考虑从一个负点右移到一个正点的时候,如果都不会出现不用右移的情况(也就是不会有直接覆盖正点的情况)答案就是上一次的总长度减去点个数乘以区间长度之差
但是如果出现了这种情况呢?首先我们离线处理是已经将区间长度从小到大排序,所以当前区间长度是这种情况下一个区间的长度肯定还会是这种情况。
所以遇到这种情况我们需要减去计算之前区间长度在这两点之间需要的移动距离,再将这两个踢出我们的考虑范围(我比较傻用了两个堆存储一个正点一个负点,由于是正值或负值是分别单调的只需要两个指针即可完成操作),同时点数减去2(成对考虑),再次计算贡献即可
pos[1]<0再分类讨论一下就好了
这种情况经过了对拍的检验应该是没什么问题的但是数据没读全也不知道咋回事
然后正解是怎么处理这个子任务的呢?我们可以把任务编号看成x轴,坐标位置看成y轴点出所有的点再将相邻两点连线是这个样子:

我们将相邻两点之间连线的长度叫做\(p[i]\),当前区间长度为\(L\),如果任意\(p[i]>L\)那么答案就是\(\sum (p[i]-L)\)
但是如果存在\(p[i]<=L\)呢,若\(a,b\)连线长度\(p<=L\),那么我们将这两点删去,将\(a-1,b+1\)之间连新的线

你会发现由于连线长度是单调的非常好处理,实际上我的做法也是在模拟类似的操作
再考虑没有第四个子任务的限制怎么做.首先我们可以预处理,对于一段连续的任务如果是单调的,那么我们只用保留头和尾就可以了,中间的显然不用管,那么这时候再仿照上面画出图像

会发现由于并没有任务4的限制预处理后还可能出现x这样的点,这时候连线长度就不是递增的了,怎么办呢?
我们把所有长度放入一个小根堆中,每次对于一个新区间长度L,如果堆顶长度p小于等于L,也就是说达到x-1时就已经覆盖了x,比如图中\(x-1\)到\(x\)这段折线,我们就把它相邻两段连线包括它本身换成另一条折线,这样显然是最优情况
所以我们还需要记录连线的前驱后继来个映射,还要用链表/map记录下对应位移序列之类的搞一搞,统计方案用上面一样的方法,不断更新连线段数和连线总长就好了
由于每段只会进堆一次,时间复杂度\(O(NlogN)\)
但是这道题细节巨坑...题解只说了在首尾要特判,但其实链表之类搞一搞真挺烦的,所以并没有写代码...
代码:
这是标程代码...我太懒了并没有自己写一份
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
int n,m;
ll tot,ans[maxn];
vector<int> x;
vector<pair<int,int> > a;
map<int,int> mp;
inline ll calc(ll k){
if(!mp.empty()&&mp.begin()->second<0)
return tot-(mp.size()-1)*k;
else
return tot-mp.size()*k;
}
inline void solve(){
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;
int t=0;
for(int i=0;i<x.size();++i){
tot+=abs(x[i]);
mp[i]=x[i];
q.push(make_pair(abs(x[i]),i));
}
while(!q.empty()){
int id=q.top().second,tmp=q.top().first;q.pop();
map<int,int>::iterator p=mp.lower_bound(id);
if(p==mp.end()||p->first!=id||abs(p->second)!=tmp)
continue;
while(t<a.size()&&abs(p->second)>a[t].first)
ans[a[t].second]=calc(a[t].first),++t;
if(p!=mp.begin())
if(p!=prev(mp.end())){
tmp=p->second,tot-=abs(p->second);
tmp+=prev(p)->second,tot-=abs(prev(p)->second);
tmp+=next(p)->second,tot-=abs(next(p)->second);
mp.erase(prev(p));
mp.erase(next(p));
p->second=tmp,tot+=abs(tmp);
q.push(make_pair(abs(tmp),id));
}
else{
tot-=abs(p->second);
mp.erase(p);
}
else if(p->second>0)
if(p!=prev(mp.end())){
tmp=p->second,tot-=abs(p->second);
tmp+=next(p)->second,tot-=abs(next(p)->second);
mp.erase(next(p));
if(tmp){
p->second=tmp,tot+=abs(tmp);
q.push(make_pair(abs(tmp),id));
}
else
mp.erase(p);
}
else{
tot-=abs(p->second);
mp.erase(p);
}
}
while(t<a.size())
ans[a[t].second]=calc(a[t].first),++t;
}
int main(){
freopen("z.in","r",stdin);
freopen("z.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=0,p,last=0;i<n;++i){
scanf("%d",&p);
if(p==last)
continue;
if(!x.empty()&&(x.back()<0&&p<last||x.back()>0&&p>last))
x.back()+=p-last;
else
x.push_back(p-last);
last=p;
}
for(int i=0,l;i<m;++i){
scanf("%d",&l);
a.push_back(make_pair(l,i));
}
sort(a.begin(),a.end());
solve();
for(int i=0;i<m;++i)
printf("%lld\n",ans[i]);
return 0;
}
[NOIP10.4模拟赛]3.z题解--思维的更多相关文章
- [NOIP10.6模拟赛]1.merchant题解--思维+二分
题目链接: while(1)gugu(while(1)) 闲扯 考场上怕T2正解写挂其他两题没管只打了暴力,晚上发现这题思维挺妙的 同时想吐槽出题人似乎热衷卡常...我的巨大常数现在显露无疑QAQ 分 ...
- [NOIP10.5模拟赛]3.c题解--思维
题目链接 这次不咕了 https://www.luogu.org/problemnew/show/AT2389 闲扯 考场20分爆搜走人 \cy 话说这几天T3都很考验思维啊 分析 我们先钦定一只鸡( ...
- [NOIP10.6模拟赛]2.equation题解--DFS序+线段树
题目链接: 咕 闲扯: 终于在集训中敲出正解(虽然与正解不完全相同),开心QAQ 首先比较巧,这题是\(Ebola\)出的一场模拟赛的一道题的树上强化版,当时还口胡出了那题的题解 然而考场上只得了86 ...
- [NOIP10.3模拟赛]3.w题解--神奇树形DP
题目链接: 咕 闲扯: 这题考场上把子任务都敲满了,5个namespace,400行11k 结果爆0了哈哈,因为写了个假快读只能读入一位数,所以手测数据都过了,交上去全TLE了 把边分成三类:0. 需 ...
- [NOIP10.4模拟赛]2.y题解--折半搜索+状压计数
题目链接: 咕 闲扯: 这题暴力分似乎挺多,但是一些奇奇怪怪的细节没注意RE了,还是太菜了 分析: 首先我们考虑最naiive的状压DP ,\(f[u][v][state]\)表示u开头,v结尾是否存 ...
- [NOIP10.5模拟赛]1.a题解--离散化+异或线段树
题目链接: 咕咕咕 https://www.luogu.org/problemnew/show/CF817F 闲扯 在Yali经历几天折磨后信心摧残,T1数据结构裸题考场上连暴力都TM没打满 分析 观 ...
- contesthunter暑假NOIP模拟赛第一场题解
contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...
- 模拟赛 提米树 题解 (DP+思维)
题意: 有一棵棵提米树,满足这样的性质: 每个点上长了一定数量的Temmie 薄片,薄片数量记为这个点的权值,这些点被标记为 1 到 n 的整数,其 中 1 号点是树的根,没有孩子的点是树上的叶子. ...
- DYOJ 【20220317模拟赛】瞬间移动 题解
瞬间移动 题意 三维空间中从 \((0,0,0)\) 开始,每次移动 1,问刚好走 \(N\) 次能到 \((X,Y,Z)\) 的方案数 \(N\le10^7\),答案模 \(998244353\) ...
随机推荐
- geth入门命令和miner.start返回null的问题
geth –datadir “./ethdev” –nodiscover console 2>>geth.log //geth 进入控制台 –datadir 指定链的目录 与公有链区分开 ...
- Flutter移动电商实战 --(34)列表页_小BUG的修复
当高粱酒的子类没有数据返回的时候就会报错. 解决接口空数据报错的问题 没有数据的时候,给用户一个友好的提示, 我们没有数据的时候还要告诉用户,提示一下他没有数据,在我们的右侧列表的build方法内去判 ...
- $this->request->post 和input 区别
$this->request->post 和input 区别 Request是对象,而input是内置函数 文章来源:刘俊涛的博客 欢迎关注,有问题一起学习欢迎留言.评论
- MyBatis——特殊传参问题小结
近期在写系统报表API的时候遇到MyBatis中的一些特殊写法: 1. 传入两个参数(一般情况下我们更多的是传入一个对象或者map) public List<MarketVehicleModel ...
- laydate V5-0-8动态设置min值
laydate通过设置min,max值来对用户输入的时间做约束 laydate v1.0版本 //日期插件 var start={ elem:"#start", format:&q ...
- 18.flannel
18.flannel docker有四种常用网络 bridge joined opended 直接共享使用节点的网络名称空间 none k8s网络通信: 容器间的通信: 同一个Pod内的多个容器之间通 ...
- nginx虚拟机无法访问解决
.重要:修改配置文件使用虚拟机,否则怎么配置都不生效,添加如下用户 [root@host---- html]# ll /etc/nginx/nginx.conf -rw-r--r-- root roo ...
- CockroachDB学习笔记——[译]CockroachDB是如何进行分布式原子事务的
原文:How CockroachDB Does Distributed, Atomic Transactions 原文链接:https://www.cockroachlabs.com/blog/how ...
- Spark快速大数据分析之RDD基础
Spark 中的RDD 就是一个不可变的分布式对象集合.每个RDD 都被分为多个分区,这些分区运行在集群中的不同节点上.RDD 可以包含Python.Java.Scala中任意类型的对象,甚至可以包含 ...
- Flutter中的基础组件之一
一.Text文本组件(单一格式的文本) 是具有单一风格的文本字符串,可以跨多行显示,也可全部显示在同一行中,具体显示样子,取决于布局约束. 常用属性: 1.overflow : TextOverflo ...