智乃的k线段区间

在数轴上有 N N N条线段,第 i i i条线段的左右端点分别为 l i , r i l_i,r_i li,ri

定义一段区间 [ L , R ] [L,R] [L,R]包含第 i i i条线段,当且仅当 L ≤ l i ≤ r i ≤ R L \leq l_i \leq r_i \leq R LliriR

智乃想要知道 L , R ∈ [ 1 , M ] L,R\in[1,M] L,R[1,M] L ≤ R L\leq R LR时,有多少个区间 [ L , R ] [L,R] [L,R]包含至少 K K K条线段。

输入:
第一行输入三个正整数 N , M , K ( 1 ≤ K ≤ N ≤ 1 0 5 , 1 ≤ M ≤ 1 0 9 ) N,M,K(1\leq K \leq N \leq 10^5,1\leq M \leq 10^9) N,M,K(1KN105,1M109)
接下来 N N N行,每行输入两个正整数 l i , r i ( 1 ≤ l i ≤ r i ≤ M ) l_i,r_i(1\leq l_i \leq r_i \leq M) li,ri(1liriM)

输出:
仅一行一个非负整数,表示问题的答案。

样例1:
输入

6 9 3 3 5 4 6 5 7 8 8 8 8 8 8

6 9 3
3 5
4 6
5 7
8 8
8 8
8 8```

输出
--

 19

思路:我们先预处理出所有“包含K条线段”的最小区间。这一步预处理过程我们可以借助std::priority_queue,然后就可以选择这k条线段左右两边的所有点进行乘法原理,然后考虑某些区间可能会重复,那么我们右边区间每次只选一部分。

代码:`#include<bits/stdc++.h>
#define int long long
#define x first
#define y second
#define endl ‘\n’
#define pq priority_queue
using namespace std;
typedef pair<int,int> pii;

bool cmp(pii x, pii y){
return x.second < y.second;
}

void solve(){
int n, m, k;
cin >> n >> m >> k;
vectora(n + 1);
for(int i = 1;i <= n;i ++){
cin >> a[i].first >> a[i].second;
}
int ans = 0;
sort(a.begin(), a.end(), cmp);
priority_queue<int,vector,greater>q;
for(int i = 1;i <= n;i ++){
int e;
if(i == n){
e = m - a[i].second + 1;
}else{
e = a[i + 1].second - a[i].second;
}
q.push(a[i].first);
while(q.size() > k)
q.pop();
if(q.size() == k)
ans += q.top() * e;
}
cout << ans << endl;
}

signed main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t = 1;
while(t–)
{
solve();
}
return 0;
}
`

  • 8
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

临江浪怀柔ℳ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值