您的位置:首页 > 其它

51NOD 1672 区间交

2017-04-03 10:35 344 查看

题目链接:

https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1672

题解:

这里的数据的范围给的是1e5,所以,对于找到区间以后,一遍的循环是不会超时的。这里的难点主要是怎么找到满足条件的区间。我们可以这么去思考,先将区间的一个端点固定,去找另一个满足条件的最大的端点(因为这里的ai已经保证全部都是大于0的, 没有负数,所以,一定是找范围大的)。自己是参考了网上大神的代码,用了mulitset来进行一个区间的维护,感觉写的很妙。

代码:

#include <set>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define met(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
typedef long long ll;
const int maxn = 100000+10;
struct node
{
int left,right;
}s[maxn];
int num[maxn];
ll sum[maxn];

int cmp(node a,node b)
{
if(a.left!=b.left)
return a.left<b.left;
return a.right<b.right;
}

multiset<int> seg;//跟set差不多,但是这个是可以重复的。
multiset<int >::iterator iter;

int n,k,m;
int main()
{
seg.clear();
scanf("%d%d%d",&n,&k,&m);
for(int i=1;i<=n;i++)
scanf("%d",&num[i]);
for(int i=0;i<m;i++)
scanf("%d%d",&s[i].left,&s[i].right);
sum[0]=0;
for(int i=1;i<=n;i++)
sum[i]=sum[i-1]+num[i];//对于结果进行预处理。
sort(s,s+m,cmp);
for(int i=0;i<k;i++)
seg.insert(s[i].right);
iter=seg.begin();//在满足条件下的初始的,最小的区间
//int ans=0;
ll ans=0;
ans=max((ll)0,sum[*iter]-sum[s[k-1].left-1]);
for(int i=k;i<m;i++)
{
seg.insert(s[i].right);
if(s[i].right>=*iter)
iter++;
ans=max(ans,sum[*iter]-sum[s[i].left-1]);
}
printf("%lld\n",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: