区间交Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1431 Accepted Submission(s): 546 Problem Description 小A有一个含有n 个非负整数的数列与m 个区间。每个区间可以表示为li,ri 。 Input 多组测试数据 Output 一行表示答案 Sample Input 5 2 3 1 2 3 4 6 4 5 2 5 1 4 Sample Output 10 Source 2016"百度之星" - 初赛(Astar Round2B) Recommend wange2014 | We have carefully selected several similar problems for you: 6373 6372 6371 6370 6369 |
借鉴:https://blog.csdn.net/bbhhtt/article/details/78311218
#include<stdio.h>
#include<queue>
#include<algorithm>
using namespace std;
#define MAX 100005
struct Node
{
int l,r;
friend bool operator <(Node a,Node b) //两个参数至少有一个是类里面的才可以省略friend
{
return a.r>b.r; //因为就是将r小的在优先队列优先删除,和l无关
}
}f[MAX];
long long sum[MAX];
bool cmp(Node a,Node b)
{
if(a.l!=b.l)
return a.l<b.l;
return a.r<b.r;//左端相等时也排序 ,不然有数据WA
}
//理解题意:
/*
假设三个区间相交
和就是最左到最右这些区间所有点的和
*/
int main()
{
int n,k,m;
int i;
long long x,maxn; //这里有个细节,虽然x可以用int型来存,但maxn是long long型,所以x也要设为long long型
while(scanf("%d%d%d",&n,&k,&m)!=EOF)
{
maxn=0;
sum[0]=0;
for(i=1;i<=n;i++)
{
scanf("%lld",&x); //区间和就是一种预处理,区间和应用通常涉及DP思想
sum[i]=sum[i-1]+x; //因为是区间的和,所以一下就反应出来是区间和
} //区间和肯定是比线段树好的呀
for(i=0;i<m;i++)
{
scanf("%d%d",&f[i].l ,&f[i].r);
}
sort(f,f+m,cmp); //...........注意怎么排画图就懂了
priority_queue <Node> q;
for(i=0;i<m;i++)
{
q.push(f[i]); //其实就是右端点入队,因为优先队列加入的是结构体且该结构体有多个元素,所以要重构运算符
while(q.size()>k)
q.pop(); //多余k,后面元素更优
if(q.size()==k) //符合,则更新maxn值
maxn=max(maxn,sum[q.top().r]-sum[f[i].l-1]); //发现一个细节,区间的相交部分。左小
}
printf("%lld\n",maxn);
}
return 0;
}