题目描述

丽江河边有 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. http协议--留

    1.http消息结构 *http客户端,即web浏览器,链接到服务器,向服务器发送一个http请求的目的 *http服务器,即web服务,接受请求,并向客户端发送http响应数据 http统一资源标识 ...

  2. FTP2

    FTP: 环境:windows, python 3.5功能:1.用户加密认证,可自行配置家目录磁盘大小2.多用户登陆3.查看当前目录(家目录权限下)4.切换目录(家目录权限下)5.上传下载,进度条展示 ...

  3. Python学习-day17 jQuery method and demo

    一:介绍: jQuery:是DOM和js的封装.jQuery是一个兼容多浏览器的javascript库,核心理念是write less,do more(写得更少,做得更多).现在大多数的pc端的网站都 ...

  4. TensorFlow dataset API 使用

    # TensorFlow dataset API 使用 由于本人感兴趣的是自然语言处理,所以下面有关dataset API 的使用偏向于变长数据的处理. 1. 从迭代器中引入数据 import num ...

  5. springboot02 Thymeleaf

    一.http协议 1. 什么是协议? 协议是交易双方共同遵守的一种约定,比如: 租房协议 , 购买协议.... 2. 什么是http协议? HTTP协议是Hyper Text Transfer Pro ...

  6. Linux网卡驱动程序对ethtool的支持和实现

    Linux 的一个显著特点就是其强大的网络功能,Linux 几乎支持所有的网络协议,并在这些协议基础上提供了丰富的应用.对 Linux 网络管理的重要性不言而喻,这些管理依赖于网络工具,比如最常用的 ...

  7. 爬虫:Scrapy7 - Scrapy终端(Scrapy shell)

    Scrapy 终端是一个交互终端,可以在未启动 spider 的情况下尝试及调试你的爬取代码.其本意是用来测试提取数据的代码,不过可以将其作为正常的 Python 终端,在上面测试任何 Python ...

  8. HDU 3874 Necklace 树状数组

    题意:求区间内不同的数的和 离线处理,按查询右端点从小到大排序,从左往右扫一遍. 记录每个数出现的上一个位置,如果该数之前没有出现过,就加上,否则就在上一个位置减去. #include <cst ...

  9. hexo 添加标签

    --- title: title #文章標題 date: 2016-06-01 23:47:44 #文章生成時間 categories: "Hexo教程" #文章分類目錄 可以省略 ...

  10. [Atcoder Grand Contest 006 F][AGC006F] Blackout [染色]

    题面 传送门 思路 首先,这个涂黑的方法我们来优化一下模型(毕竟当前这个放到矩形里面,你并看不出来什么规律qwq) 我们令每个行/列编号为一个点,令边(x,y)表示一条从x到y的有向边 那么显然只要有 ...