您的位置:首页 > 其它

HDU 5700 区间交 线段树暴力

2016-05-23 22:22 316 查看
枚举左端点,然后在线段树内,更新所有左边界小于当前点的区间的右端点,然后查线段树二分查第k大就好

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100005;
LL a
;
struct Node{
int l,r;
bool operator<(const Node &rhs)const{
if(l==rhs.l)return r<rhs.r;
return l<rhs.l;
}
}p
;
int c[N<<2];
void add(int rt,int l,int r,int x){
++c[rt];
if(l==r)return;
int m=(l+r)>>1;
if(x<=m)add(rt<<1,l,m,x);
else add(rt<<1|1,m+1,r,x);
}
int ask(int rt,int l,int r,int k){
if(l==r)return l;
int m=(l+r)>>1;
if(c[rt<<1|1]>=k)ask(rt<<1|1,m+1,r,k);
else ask(rt<<1,l,m,k-c[rt<<1|1]);
}
int main(){
int n,k,m;
while(~scanf("%d%d%d",&n,&k,&m)){
for(int i=1;i<=n;++i){
LL x;scanf("%I64d",&x);
a[i]=a[i-1]+x;
}
for(int i=1;i<=m;++i){
scanf("%d%d",&p[i].l,&p[i].r);
}
sort(p+1,p+1+m);
memset(c,0,sizeof(c));
int cnt=1;
LL res=0;
for(int i=1;i<=m;++i){
for(;cnt<=m&&p[cnt].l<=p[i].l;++cnt)
add(1,1,n,p[cnt].r);
if(c[1]<k)continue;
int cur=ask(1,1,n,k);
if(cur>=p[i].l)res=max(res,a[cur]-a[p[i].l-1]);
}
printf("%I64d\n",res);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: