题目描述

丽江河边有 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】 选择客栈的更多相关文章

  1. 洛谷 P1311 选择客栈 解题报告

    P1311 选择客栈 题目描述 丽江河边有 \(n\) 家很有特色的客栈,客栈按照其位置顺序从 \(1\) 到 \(n\) 编号.每家客栈都按照某一种色调进行装饰(总共 \(k\) 种,用整数 \(0 ...

  2. 洛谷P1311 选择客栈

    P1311 选择客栈 题目描述 丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从 1 到n 编号.每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一 ...

  3. Luogu P1311 选择客栈(前缀和)

    P1311 选择客栈 题意 题目描述 丽江河边有\(n\)家很有特色的客栈,客栈按照其位置顺序从\(1\)到\(n\)编号.每家客栈都按照某一种色调进行装饰(总共\(k\)种,用整数\(0\)~\(k ...

  4. 【洛谷】【st表+模拟】P1311 选择客栈

    [题目描述:] 丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从 1 到n 编号.每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖 ...

  5. P1311 选择客栈[模拟]

    题目描述 丽江河边有nn家很有特色的客栈,客栈按照其位置顺序从 11到nn编号.每家客栈都按照某一种色调进行装饰(总共 kk 种,用整数 00 ~k-1k−1 表示),且每家客栈都设有一家咖啡店,每家 ...

  6. [NOIP2011] 提高组 洛谷P1311 选择客栈

    题目描述 丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从 1 到n 编号.每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖啡店均 ...

  7. 洛谷 P1311 选择客栈

    题目描述 丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从 1 到n 编号.每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖啡店均 ...

  8. 2011 luogu P1311 选择客栈

    题目描述 丽江河边有 nn 家很有特色的客栈,客栈按照其位置顺序从 1 到 n 编号.每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖 ...

  9. 洛谷 P1311 选择客栈 —— 水题

    题目:https://www.luogu.org/problemnew/show/P1311 看每个位置能否成为咖啡店,然后作为客栈和前面配对即可. 代码如下: #include<iostrea ...

  10. 洛谷——P1311 选择客栈

    https://www.luogu.org/problem/show?pid=1311 题目描述 丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从 1 到n 编号.每家客栈都按照某一种色调进行装饰 ...

随机推荐

  1. CodeIgniter学习笔记三:扩展CI的控制器、模型

    一.扩展CI中的控制器 有时需要对CI中的控制器作统一操作,如进行登录和权限验证,这时就可以通过扩展CI控制器来实现. 扩展CI控制器只需要在application/core文件夹中建一个继承自CI_ ...

  2. 解决使用Oracle数据库,项目启动由于表原因无法成功启动问题

    1.仔细看异常信息,如果出现一个  翻译过来是 不仅仅这一张表,那就说明,在连接数据库,定位到表的时候有多张表,不知道连哪一张. 原因: 有多个用户,这两个用户下有相同的表. 就算是在不同的表空间也不 ...

  3. 课时2:用python设计第一个游戏

    目录: 一.第一个小游戏 二.缩进 三.BIF 四.课时02课后习题及答案 ********************* 一.第一个小游戏 ********************* # p2_1.py ...

  4. 融合模型Aggregation

    从一堆弱分类器融合得到强分类器. 比如假设现在你只能水平或竖直线分割,那么无论如何都分不好,但是假设组合三次分割,就会得到如图所示的一个较好的分割线. 再比如,PLA 融合后有large margin ...

  5. qemu中是怎么模拟的新的设备

    kvm_cpu_exec 和demo中演示的一样

  6. TypeScript 3.0下react默认属性DefaultProps解决方案

    ts和react的默认属性的四种解决方案 Non-null assertion operator(非空断言语句) Component type casting(组件类型重置) High order f ...

  7. sqlserver 汉字转拼音 索引 函数

    IF OBJECT_ID('[fn_GetPinyin]') IS NOT NULL DROP FUNCTION [fn_GetPinyin] GO create function [dbo].[fn ...

  8. ES6 学习体会

    第一部分: 1.初始化项目 npm init -y 2.安装ES6 环境 .babelrc 文件 babel-cli -g babel-ecmascript2015 babel-cli --save- ...

  9. 利用反射修改final数据域

    当final修饰一个数据域时,意义是声明该数据域是最终的,不可修改的.常见的使用场景就是eclipse自动生成的serialVersionUID一般都是final的. 另外还可以构造线程安全(thre ...

  10. winform中key读取修改

    根据key name的名称读取value-----读取使用ConfigurationManager.AppSettings读取容易没读取到根目录中的key public string GetXml(s ...