[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\) ...
随机推荐
- tocke - 加密
//获取32位随机字符串 $randTocke = getRandChar($length); //当前脚本运行时间, 单位为十万分之一毫秒 $timestamp = $_SERVER['REQUES ...
- Vue中可用的判断对象是否为空的方法
vue有两个方法可用 1. JSON.stringify(evtValue)=='{}' 2. Object.keys(xxx).length==0 js判断对象是否为空对象的几种方法 1.将json ...
- linux下什么工具可以用来纠正文件中的拼写和排版错误?
答: ispell,官网在此
- [Java复习] Spring Framework 框架小结
Spring 总共大约有 20 个模块,由 1300 多个不同的文件构成. 而这些组件被分别整合在 核心容器 (Core Container), AOP(Aspect Oriented Pro ...
- [!] The version of CocoaPods used to generate the lockfile (1.4.0.beta.1) is higher than the version of the current executable (1.3.0.beta.1). Incompatibility issues may arise.
今天在看一个开源Demo代码的时候,需要执行pod install命令,直接报错如下: 解决方法: 执行:pod update 命令更新资源库即可.
- ubuntu安装以及卸载软件
dpkg安装以及卸载软件 deb文件是linux发行版debian系统的安装包格式,还有像基于debian系统的发型版ubuntu等系统就是使用的deb格式安装包,我们可以使用dpkg命令进行安装管理 ...
- IIS 6.0的web园 最大工作进程数细谈
这篇文章主要介绍了IIS 6.0的web园 最大工作进程数,需要的朋友可以参考下:(摘自:http://www.jb51.net/article/84817.htm) IIS 6.0允许将应用程序池配 ...
- JS之ajax实现注册页,小文件传输
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 鼠标拖拉div宽度
先看效果 先进入页面 当鼠标停留在中间div时,鼠标变成双箭头 点击拖拉 往右边拉 往最左边拉 代码 <!DOCTYPE html> <html> <head> & ...
- 学习笔记:CentOS7学习之十七: Linux计划任务与日志的管理
目录 学习笔记:CentOS7学习之十七: Linux计划任务与日志的管理 17.1 计划任务-at-cron-计划任务使用方法 17.1.1 at计划任务的使用 17.1.2 查看和删除at将要执行 ...