一道欺负我智商的题。。。

本来想打单调队列优化dp的,结果看到算法标签就点了此题

洛谷题面

首先你要理解题意,蒟蒻理解了好久。它就是说,给你一个由1和-1组成的数列,让你分成m段,并让这m段区间和最大值最小,还要求多种方案时字典序最小。

我也不知道大佬怎么做的,反正我不会高斯消元。。。

哦,对了,如果输入的是0,表示他不喜欢则那一位为-1。

设总和为S。区间和最小值为ans。后缀和为sum[],后缀中0的个数为cnt[]。

为什么是后缀,往后看。。。

首先考虑特殊情况:

  • 全是1 显然答案为ans=ceil(S/m);ceil()是向上取整。
  • 全是-1 ans=ceil(abs(S)/m)
  • 一半全1,一半全-1 比如11111-1-1-1可以变成11(111-1-1-1),括号里为0,可以与任意区间搭配,于是变成了上面的情况。

所以ans=ceil(abs(S)/m),简易证明:你可以用第三中方法狂消1和-1直到只有一种数,剩下来的数的个数是abs(S)。

如果abs(S)=0且能分的区间不足m那就另当别论。。。

由于我太菜了,还有情况没考虑就多多包含

先预处理sum[],ans,cnt[];

  • S=0
  • cnt[1]>=m,此时找sum[i]=0的点i,用单调队列维护找出字典序最小的一条即可。
  • cnt[1]<m,ans>0,和下面一起处理。
  • S!=0 sum的每一种取值分开考虑。

设上一个选的为last,则这一个i能选要满足abs(sum[last+1]-sum[i+1])<=ans,那么我们枚举sum[i+1]的取值时就可以直接从sum[last+1]-ans到sum[last+1]+ans。
  并且abs(sum[i+1]/m'(即剩下要选的数量))要满足小于等于ans,i还有后面的数不能超过m'个。
  然后跑单调队列就完啦,不要告诉我你切黑题还不会这个。。。

实现起来还有不少细节,比如负数下标之类的,仔细看下应该都能懂

如果你想TLE的话deque走起

#include<cstdio>
#include<algorithm>
const int N=5e5+;
int a[N],sum[N],cnt[N],tot;
struct node
{
int l,r,val;
}p[N<<];
inline int newnode(int l,int r,int val)
{
p[++tot]=(node){l,r,val};
return tot;
}
struct que
{
int start,end,len;
inline void push_back(int x)
{
if(!len)start=end=newnode(,,x);
else p[end].r=newnode(end,,x),end=p[end].r;
++len;
}
inline int empty(){return !len;}
inline int front(){return p[start].val;}
inline int back(){return p[end].val;}
inline void pop_front(){start=p[start].r;--len;}
inline void pop_back(){end=p[end].l;--len;}
inline void push(int x)
{
while(!empty()&&a[back()]>a[x])pop_back();
push_back(x);
}
}dui[N<<],dui1[N<<],*q=dui+N,*q1=dui1+N;
inline int min(const int &x,const int &y)
{return a[x]<a[y]?x:y;}
int main()
{
int n,m,ans;scanf("%d%d",&n,&m);
for(int i=;i<=n;++i)scanf("%d%d",&a[i],&sum[i]),sum[i]=sum[i]?:-;
for(int i=n-;i;--i)sum[i]+=sum[i+];
for(int i=n;i;--i){cnt[i]+=cnt[i+];if(!sum[i])++cnt[i];}
cnt[n+]=-;
// for(int i=1;i<=n+1;++i)printf("%d %d\n",sum[i],cnt[i]);
int s=sum[];
ans=s?(abs(s)-)/m+:cnt[]<m;//printf("ss%d\n",ans);
if(ans)
{
a[n+]=n+;int la=;
for(int i=;i<=n;++i)
q1[sum[i]].push_back(i-);
for(int i=;i<m;++i)
{
int aa=n+;
for(int j=sum[la+]-ans;j<=sum[la+]+ans;++j)
{
if((abs(j)+m-i-)/(m-i)>ans)continue;
while(!q1[j].empty()&&n-q1[j].front()>=m-i){if(q1[j].front()>la)q[j].push(q1[j].front());q1[j].pop_front();}
while(!q[j].empty()&&q[j].front()<=la){q[j].pop_front();}
if(!q[j].empty())aa=min(aa,q[j].front());
}
la=aa;
printf("%d ",a[aa]);
}
}
else
{
for(int i=,j=;i<m;++i)
{
for(;cnt[j+]>=m-i;++j)
if(!sum[j+])
q[].push(j);
printf("%d ",a[q[].front()]);
q[].pop_front();
}
}
printf("%d\n",a[n]);
return ;
}

HNOI2013旅行的更多相关文章

  1. 3141: [Hnoi2013]旅行 - BZOJ

    Description Input 第一行为两个空格隔开的正整数n, m,表示旅行的城市数与旅行所花的月数.接下来n行,其中第 i行包含两个空格隔开的整数Ai和Bi,Ai表示他第i个去的城市编号.Bi ...

  2. bzoj3141: [Hnoi2013]旅行

    Description   Input 第 一行为两个空格隔开的正整数n, m,表示旅行的城市数与旅行所花的月数.接下来n行,其中第 i行包含两个空格隔开的整数Ai和Bi,Ai表示他第i个去的城市编号 ...

  3. 【LG3229】[HNOI2013]旅行

    题面 洛谷 题解 勘误:新的休息点a需要满足的条件2为那一部分小于等于ans 代码 \(100pts\) #include <iostream> #include <cstdio&g ...

  4. BZOJ3141:[HNOI2013]旅行

    浅谈队列:https://www.cnblogs.com/AKMer/p/10314965.html 题目传送门:https://www.lydsy.com/JudgeOnline/problem.p ...

  5. [HNOI2013]题解

    代码在最后 [HNOI2013]比赛 记忆化搜索 把每一位还需要多少分用\(27\)进制压进\(long\) \(long\),\(map\)记忆化一下即可 [HNOI2013]消毒 先考虑在二维平面 ...

  6. Hnoi2013题解 bzoj3139~3144

    话说好久没写题(解)了.. 先贴份题解:http://wjmzbmr.com/archives/hnoi-2013-%E9%A2%98%E8%A7%A3/(LJ神题解..Lazycal表示看不懂..) ...

  7. # HNOI2012 ~ HNOI2018 题解

    HNOI2012 题解 [HNOI2012]永无乡 Tag:线段树合并.启发式合并 联通块合并问题. 属于\(easy\)题,直接线段树合并 或 启发式合并即可. [HNOI2012]排队 Tag:组 ...

  8. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  9. 【BZOJ3143】【HNOI2013】游走 && 【BZOJ3270】博物馆 【高斯消元+概率期望】

    刚学完 高斯消元,我们来做几道题吧! T1:[BZOJ3143][HNOI2013]游走 Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小 ...

随机推荐

  1. 统计学习方法c++实现之七 提升方法--AdaBoost

    提升方法--AdaBoost 前言 AdaBoost是最经典的提升方法,所谓的提升方法就是一系列弱分类器(分类效果只比随机预测好一点)经过组合提升最后的预测效果.而AdaBoost提升方法是在每次训练 ...

  2. 九九乘法表的python复习

    九九开始的复习 这周复习之前的学的知识关于range函数,gormat函数,print的使用总结一下 从一个小例子开始,开始我的回顾吧, 大家都是从那个九九乘法表开始的数学之旅,从一一得一,开始了我们 ...

  3. Intellij IDEA创建maven项目无java文件问题

    在idea开发工具中创建工程时,点击右键没有创建包.接口.java类的提示, 如图: 解决之前的项目目录为: 针对这种情况,对idea开发工具做以下设置. 选择File->Project Str ...

  4. 一次ajax调用,发送了两次请求(一次为请求方法为option,一次为正常请求)

    在项目了开发时遇见一个奇怪的现象,就是我在js里面发送一次ajax请求,在浏览器network那边查询到的却是发送了两次请求,第一次的Request Method参数为OPTIONS,第二次的Requ ...

  5. 奔跑吧DKY——团队Scrum冲刺阶段-Day 2

    今日完成任务 各个成员今日完成的任务(如果完成的任务为开发或测试任务,需给出对应的Github代码签入记录截图:如果完成的任务为调研任务,需给出对应的调研总结博客链接:如果完成的任务为学习技术任务,需 ...

  6. web14 validation.xml配置 登录验证文件配置

    电影网站:www.aikan66.com 项目网站:www.aikan66.com 游戏网站:www.aikan66.com 图片网站:www.aikan66.com 书籍网站:www.aikan66 ...

  7. EF三种编程方式详细图文教程(C#+EF)之Model First

    Model First Model First我们称之为“模型优先”,这里的模型指的是“ADO.NET Entity Framework Data Model”,此时你的应用并没有设计相关数据库,在V ...

  8. Java文件写入时是否覆盖

    这个是和服务器读数据结合着来的,是向服务器文件写数据,这就碰到了是否覆盖以前写的数据的问题,看FileWriter();的参数后面的参数名叫append,用词典查是附加的意思,灵机一动,改成false ...

  9. Beta Scrum Day 5 — 听说

    听说

  10. linux上传的命令

    pscp D:\apache-tomcat-8.0.38\webapps\GameDataServer.zip root@112.74.32.215:/usr/local/tools/tomcat/a ...