ST表【p1311】 选择客栈
题目描述
丽江河边有 n 家很有特色的客栈,客栈按照其位置顺序从 1 到 n 编号。每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0~k-1 表示),且每家客栈都设有一家咖啡店,每家咖啡店均有各自的最低消费。
两位游客一起去丽江旅游,他们喜欢相同的色调,又想尝试两个不同的客栈,因此决定分别住在色调相同的两家客栈中。晚上,他们打算选择一家咖啡店喝咖啡,要求咖啡店位于两人住的两家客栈之间(包括他们住的客栈),且咖啡店的最低消费不超过 p 。
他们想知道总共有多少种选择住宿的方案,保证晚上可以找到一家最低消费不超过 p 元的咖啡店小聚。
分析
很明显维护两个颜色相同的区间最小值,取每次取min判断是否不超过p即可.
一 :O(n^3)做法,就是暴力嘛 emmm 略过了
二 :O(假的n^3)做法,时间复杂度并不会证明
数组last记录每个位置i的上一个相同颜色的位置
数组head[color]记录颜色color最后一次出现的位置
记录完之后就类似链式前向星地跑就可以了
吸氧之后可以70pts
不吸氧的话60pts
代码:
#include<bits/stdc++.h>
#define IL inline
#define RI register int
#define N 200008
#define ls o<<1
#define rs o<<1|1
IL void read(int &x){
int f=1;x=0;char s=getchar();
while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();}
x*=f;
}
int n,k,p,ans;
int ST[N][21];
int head[N],last[N];
//k为色调数目,p为最低最多能花的钱.
struct STbiao
{
IL void pre()
{
for(RI j=1;(1<<j)<=n;j++)
for(RI i=1;i+(1<<j)-1<=n;i++)
ST[i][j]=std::min(ST[i][j-1],ST[i+(1<<(j-1))][j-1]);
}
IL int query(int l,int r)
{
int k=log2(r-l+1);
return std::min(ST[l][k],ST[r-(1<<k)+1][k]);
}
}st;
int main()
{
read(n),read(k),read(p);
for(RI i=1,col;i<=n;i++)
{
read(col),read(ST[i][0]);
last[i]=head[col];
head[col]=i;
}
st.pre();
for(RI c=0;c<k;c++)
for(RI i=head[c];i;i=last[i])
for(RI j=last[i];j;j=last[j])
if(st.query(j,i)<=p)ans++;
printf("%d",ans);
}
三 考虑优化ST
优化思想借鉴于 @ShawnZhou
我们可以再维护两个数组pre和cnt
pre[i]数组记录到当前位置颜色为i的价值小于等于p的客栈个数
cnt[i]数组记录到当前位置颜色i出现次数
因此我们可以减少枚举次数,从而达到优化时间的目的。
-----------------AC代码-----------------
#include<bits/stdc++.h>
#define IL inline
#define RI register int
#define N 200008
#define ls o<<1
#define rs o<<1|1
IL void read(int &x){
int f=1;x=0;char s=getchar();
while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();}
x*=f;
}
int n,k,p,ans;
int ST[N][21];
int head[N],last[N],color[N],cnt[N],pre[N];
//k为色调数目,p为最低最多能花的钱.
struct STbiao
{
IL void pre()
{
for(RI j=1;(1<<j)<=n;j++)
for(RI i=1;i+(1<<j)-1<=n;i++)
ST[i][j]=std::min(ST[i][j-1],ST[i+(1<<(j-1))][j-1]);
}
IL int query(int l,int r)
{
int k=log2(r-l+1);
return std::min(ST[l][k],ST[r-(1<<k)+1][k]);
}
}st;
int main()
{
read(n),read(k),read(p);
for(RI i=1,col;i<=n;i++)
read(color[i]),read(ST[i][0]);
st.pre();
for(RI i=1;i<=n;i++)
{
if(!head[color[i]])
{
cnt[color[i]]++;
head[color[i]]=i;
}
else
{
if(st.query(head[color[i]],i)<=p)
ans+=cnt[color[i]],pre[color[i]]=cnt[color[i]];
//如果当前位置与上一颜色相同位置之间有任意一家客栈的花费小于等于p
//那么我们就可以选择当前位置的客栈与更之前位置的客栈
//并更新可以对答案贡献的数组.
else
ans+=pre[color[i]];
cnt[color[i]]++;head[color[i]]=i;
}
}//这一层for即为优化后的,其他位置并没有改动。
printf("%d",ans);
}
ST表【p1311】 选择客栈的更多相关文章
- 洛谷 P1311 选择客栈 解题报告
P1311 选择客栈 题目描述 丽江河边有 \(n\) 家很有特色的客栈,客栈按照其位置顺序从 \(1\) 到 \(n\) 编号.每家客栈都按照某一种色调进行装饰(总共 \(k\) 种,用整数 \(0 ...
- 洛谷P1311 选择客栈
P1311 选择客栈 题目描述 丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从 1 到n 编号.每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一 ...
- Luogu P1311 选择客栈(前缀和)
P1311 选择客栈 题意 题目描述 丽江河边有\(n\)家很有特色的客栈,客栈按照其位置顺序从\(1\)到\(n\)编号.每家客栈都按照某一种色调进行装饰(总共\(k\)种,用整数\(0\)~\(k ...
- 【洛谷】【st表+模拟】P1311 选择客栈
[题目描述:] 丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从 1 到n 编号.每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖 ...
- P1311 选择客栈[模拟]
题目描述 丽江河边有nn家很有特色的客栈,客栈按照其位置顺序从 11到nn编号.每家客栈都按照某一种色调进行装饰(总共 kk 种,用整数 00 ~k-1k−1 表示),且每家客栈都设有一家咖啡店,每家 ...
- [NOIP2011] 提高组 洛谷P1311 选择客栈
题目描述 丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从 1 到n 编号.每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖啡店均 ...
- 洛谷 P1311 选择客栈
题目描述 丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从 1 到n 编号.每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖啡店均 ...
- 2011 luogu P1311 选择客栈
题目描述 丽江河边有 nn 家很有特色的客栈,客栈按照其位置顺序从 1 到 n 编号.每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖 ...
- 洛谷 P1311 选择客栈 —— 水题
题目:https://www.luogu.org/problemnew/show/P1311 看每个位置能否成为咖啡店,然后作为客栈和前面配对即可. 代码如下: #include<iostrea ...
- 洛谷——P1311 选择客栈
https://www.luogu.org/problem/show?pid=1311 题目描述 丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从 1 到n 编号.每家客栈都按照某一种色调进行装饰 ...
随机推荐
- Nuget 异常引用记录
事件描述 Nuget未能将packages.config中的dll成功引入项目中 解决办法 从Nuget中删除对NewtonSoft.Json的引用并重新对NewtonSoft.Json 4.5.0. ...
- WIN10把照片查看器设为默认看图软件
WIN10默认是PHOTO,没有以前WIN7的照片查看器好用,要改回来的方法如下: 在注册表HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Photo ...
- Flask 教程精简版之一(系列片)
Flask 教程精简版之一(系列片) 现在连教程都有精简版 准备 1.要学会 Flask 之前必须掌握 Python 基本使用. 2.会使用简单的 HTML 效果更加 3.若想练气功必须先自暴自弃 简 ...
- 【转载】Unity插件研究院之自动保存场景
原文: http://wiki.unity3d.com/index.php?title=AutoSave 最近发现Unity老有自动崩溃的BUG. 每次崩溃的时候由于项目没有保存所以Hierarch ...
- 【视觉SLAM14讲】ch4心得与课后题答案【仅供参考】
答案: Q1:验证SO(3) SE(3) Sim(3)关于乘法成群 SO(3) : 由P64最开始可知,乘法代表了旋转,而SO(3)是旋转矩阵的集合, SE(3) Sim(3) 同理(最基础的部分 ...
- hadoop-eclipse环境搭建(二)
Eclipse插件配置 第一步:把我们的"hadoop-eclipse-plugin-1.0.0.jar"放到Eclipse的目录的"plugins"中,然后重 ...
- 九 DIP 依赖倒置原则
首先看定义: 1.高层模块不依赖于低层模块,两者都应该依赖于抽象层 2.抽象不能依赖于细节,细节必须依赖于抽象 首先,模块是个抽象的概念,可以大到一个系统中的子系统作为一个模块,也可以是某个子系统中的 ...
- android DOM解析Xml
文章转自:http://blog.sina.com.cn/s/blog_a661f16c0101d5qp.html People类是自己写的一个类,主要保存各个字符串数据. 由于没学过Xml语法只 ...
- C++寒假学习计划
课程 中国大学mooc西北工业大学c++程序设计 理由 本课程有48节,章节分类清晰,由许多小知识块组成,条例清晰便于学习,由基础开始,由浅入深,适合我这种小白. 计划 从2.8号至2.28除去2.1 ...
- redis单线程问题
1.redis的单线程指的是什么单线程?同一个时间点只处理一个客户端的连接,也就是redis网络模块的单线程. 2.redis为什么设计成单线程 具体作者怎么想的,我不知道,我说一下我的理解(1)re ...