基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
小A有一个含有n个非负整数的数列与m个区间,每个区间可以表示为li,ri。
它想选择其中k个区间, 使得这些区间的交的那些位置所对应的数的和最大。(是指k个区间共同的交,即每个区间都包含这一段,具体可以参照样例)
在样例中,5个位置对应的值分别为1,2,3,4,6,那么选择[2,5]与[4,5]两个区间的区间交为[4,5],它的值的和为10。
Input
第一行三个数n,k,m(1<=n<=100000,1<=k<=m<=100000)。 接下来一行n个数ai,表示小A的数列(0<=ai<=10^9)。 接下来m行,每行两个数li,ri,表示每个区间(1<=li<=ri<=n)。
Output
一行表示答案
Input示例
5 2 3 1 2 3 4 6 4 5 2 5 1 4
Output示例
10
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<string.h>
#include<vector>
#define maxn 100005
#define ll long long
using namespace std;
struct node
{
ll st;
ll la;
bool operator <(const node &x)
{
return st<x.st;
}
}ac[maxn];
ll a[maxn];
ll sum[maxn];
priority_queue<int,vector<int>,greater<int> >q;
int main()
{
ll n,k,m;
memset(sum,0,sizeof(sum));
memset(a,0,sizeof(a));
scanf("%lld%lld%lld",&n,&k,&m);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
sum[i]=a[i]+sum[i-1];
}
for(int i=0;i<m;i++)
{
scanf("%lld%lld",&ac[i].st,&ac[i].la);
}
sort(ac,ac+m);
ll ans=0;
for(ll i=0;i<m;)
{
while(q.size()<k)
{
q.push(ac[i].la);
if(q.size()==k)
ans=max(ans,sum[q.top()]-sum[ac[i].st-1]);
i++;
}
while(q.size()==k)
q.pop();
}
cout<<ans<<endl;
return 0;
}
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<string.h>
#include<vector>
#define maxn 100005
#define ll long long
using namespace std;
struct node
{
ll st;
ll la;
bool operator <(const node &x)
{
return st<x.st;
}
}ac[maxn];
ll a[maxn];
ll sum[maxn];
priority_queue<int,vector<int>,greater<int> >q;
int main()
{
ll n,k,m;
memset(sum,0,sizeof(sum));
memset(a,0,sizeof(a));
scanf("%lld%lld%lld",&n,&k,&m);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
sum[i]=a[i]+sum[i-1];
}
for(int i=0;i<m;i++)
{
scanf("%lld%lld",&ac[i].st,&ac[i].la);
}
sort(ac,ac+m);
ll ans=0;
for(int i=0;i<m;i++)
{
q.push(ac[i].la);
while(q.size()>k) q.pop();
if(q.size()==k)
ans=max(ans,sum[q.top()]-sum[ac[i].st-1]);
}
cout<<ans<<endl;
return 0;
}
树状数组调了好久..
#include<iostream>
#include<string.h>
#include<algorithm>
#include<cstdio>
#define maxn 100000
#define ll long long
using namespace std;
struct Tree
{
int L;
int R;
int cover;
}tree[maxn<<2];
struct node
{
int star;
int last;
bool operator <(const node &a)
{
return star<a.star;
}
}ac[maxn];
ll sum[maxn];
void built(int p,int l,int r)
{
tree[p].L=l;
tree[p].R=r;
if(l==r)
{
tree[p].cover=0;
return ;
}
int mid=(l+r)>>1;
built(p<<1,l,mid);
built(p<<1|1,mid+1,r);
tree[p].cover=tree[p<<1].cover+tree[p<<1|1].cover;
}
void updata(int p,int x)
{
if(tree[p].L==tree[p].R)
{
tree[p].cover++;
return ;
}
int mid=(tree[p].L+tree[p].R)>>1;
if(mid>=x)
updata(p<<1,x);
else
updata(p<<1|1,x);
tree[p].cover=tree[p<<1].cover+tree[p<<1|1].cover;
}
int quety(int p,int x)
{
if(tree[p].L==tree[p].R)
return tree[p].L;
if(tree[p<<1|1].cover>=x)
return quety(p<<1|1,x);
else
return quety(p<<1,x-tree[p<<1|1].cover);
}
int main()
{
int n,k,m;
scanf("%d%d%d",&n,&k,&m);
memset(sum,0,sizeof(sum));
for(int i=1;i<=n;i++)
{
int t;
scanf("%d",&t);
sum[i]=sum[i-1]+t;
}
for(int i=1;i<=m;i++)
{
scanf("%d%d",&ac[i].star,&ac[i].last);
}
sort(ac+1,ac+m+1);
built(1,1,n);
for(int i=1;i<=k;i++)
{
updata(1,ac[i].last);
}
ll ans=0;
ac[m+1].last=0;
for(int i=k;i<=m;i++)
{
int pos=quety(1,k);
if(pos>=ac[i].star)
ans=max(ans,sum[pos]-sum[ac[i].star-1]);
updata(1,ac[i+1].last);
}
printf("%lld\n",ans);
return 0;
}