HDU 5700 区间交 线段树暴力
2016-05-23 22:22
316 查看
枚举左端点,然后在线段树内,更新所有左边界小于当前点的区间的右端点,然后查线段树二分查第k大就好
View Code
#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
相关文章推荐
- Get and Set
- 23种设计模式(9):访问者模式
- oralce group by 语句用法示例
- 有向路径检查
- AsyncTask异步加载框架原理(面试会常问到的哦!!!)
- windows下protobuf jar包的编译
- js中undefined,null,NaN的区别
- 13.6 线程的生命周期状态,线程常用的方法
- Spark学习15之用Maven编译时报 java.lang.OutOfMemoryError: PermGen space异常
- 基于Python的接口测试框架
- Java之System类的常用方法
- <1> perl概述
- android studio does not point to jvm installation
- 使用svn的合理姿势
- 【SSH网上商城项目实战27】域名空间的申请和项目的部署及发布
- 斐波那契数列11
- 设计模式之访问者模式
- SuperSocket学习笔记(一)-一个完整的例子
- <1> perl概述
- <1> perl概述