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); }
相关文章推荐
- 51NOD 1672 区间交 线段树
- 51nod 1672 区间交
- 【51Nod】1672 - 区间交(线段树 & 贪心)
- 51nod 1672 区间交
- 51nod 1672 区间交
- 51nod 1672 区间交(贪心)
- 51nod 1672 区间交【线段树】【贪心】
- 51nod 1672 区间交 (优先队列priority_queue 或 多重集合multiset)
- 51nod 1672-区间交(线段树)
- 51nod 1672 区间交【线段树、multiset】
- 51nod 1672 区间交(贪心)
- 51Nod-1672-区间交
- 51nod 1672 区间交 (经典贪心)
- 51nod-1672 区间交
- 51nod 1174 区间中最大的数【线段树】
- 51nod 1174 区间中最大的数 (线段树+RMQ)
- 【二分+Two Pointers】51Nod 1686 第K大区间
- 51Nod - 1021 石子归并 区间DP入门-分析
- 51Nod 1094 和为k 的连续区间 题解
- 51Nod 1094 和为k的连续区间