题意
题目描述
丽江河边有(n)家很有特色的客栈,客栈按照其位置顺序从(1)到(n)编号。每家客栈都按照某一种色调进行装饰(总共(k)种,用整数(0)~(k-1)表示),且每家客栈都设有一家咖啡店,每家咖啡店均有各自的最低消费。
两位游客一起去丽江旅游,他们喜欢相同的色调,又想尝试两个不同的客栈,因此决定分别住在色调相同的两家客栈中。晚上,他们打算选择一家咖啡店喝咖啡,要求咖啡店位于两人住的两家客栈之间(包括他们住的客栈),且咖啡店的最低消费不超过(p)。
他们想知道总共有多少种选择住宿的方案,保证晚上可以找到一家最低消费不超过(p)元的咖啡店小聚。
输入输出格式
输入格式:
共(n+1)行。
第一行三个整数(n,k,p),每两个整数之间用一个空格隔开,分别表示客栈的个数,色调的数目和能接受的最低消费的最高值;
接下来的(n)行,第(i+1)行两个整数,之间用一个空格隔开,分别表示(i)号客栈的装饰色调和(i)号客栈的咖啡店的最低消费。
输出格式:
一个整数,表示可选的住宿方案的总数。
输入输出样例
输入样例:
5 2 3
0 5
1 3
0 2
1 4
1 5
输出样例:
3
说明
【输入输出样例说明】
(2)人要住同样色调的客栈,所有可选的住宿方案包括:住客栈①③,②④,②⑤,④⑤,但是若选择住(4)、(5)号客栈的话,(4)、(5)号客栈之间的咖啡店的最低消费是(4),而两人能承受的最低消费是(3)元,所以不满足要求。因此只有前(3)种方案可选。
【数据范围】
对于(30 \%)的数据,有(n leq 100);
对于(50 \%)的数据,有(n leq 1,000);
对于(100 \%)的数据,有(2 leq n leq 200,000, 0<k leq 50,0 leq p leq 100,0 leq)最低消费(leq 100)。
思路
这题要倒着统计,做出来了我教你。 --Mercury
然后他做了一晚上没出来(2333)。
首先,假设有(k=1),那么怎么做呢?对于第(u)个客栈,若其前面最近的一家满足要求的咖啡店的编号为(v),那么(v)之前的所有客栈都可与(u)一起产生贡献,所以第(u)个客栈对答案的贡献为(u-v)。
如果(k eq 1),那么我们还要统计第(u)个客栈之前的和它颜色相同的客栈一共有多少家,这个可以用前缀和来完成。最后时间复杂度为(O(n))。
AC代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL N=2e5+5;
LL n,k,p,near,sum[55][N],ans;
LL read()
{
LL re=0;
char ch=getchar();
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) re=(re<<3)+(re<<1)+ch-'0',ch=getchar();
return re;
}
int main()
{
n=read(),k=read(),p=read();
for(LL i=1;i<=n;i++)
{
for(LL j=0;j<k;j++) sum[j][i]=sum[j][i-1];
LL col=read(),cost=read();
if(cost<=p) near=i;
ans+=sum[col][near];
sum[col][i]++;
}
printf("%lld",ans);
return 0;
}