HDU 5700区间交(百度之星2B)
2016-05-24 23:02
357 查看
分析:
按左端点排序,暴力枚举左端点,寻找这个左端点右边最右端被覆盖>=k次的位置,那么这个长度就是以当前节点为左端点的最大的和。那么就是一个区间覆盖+更新查询操作,用一颗线段树就可以维护。
复杂度:o(nlogn)
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <set> #include <map> #include <queue> #include <vector> #include <string> using namespace std; typedef long long LL; typedef vector <int> VI; typedef pair <int,int> PII; #define FOR(i,x,y) for(int i = x;i < y;++ i) #define IFOR(i,x,y) for(int i = x;i > y;-- i) #define pb push_back #define mp make_pair #define fi first #define se second #define lrt rt<<1 #define rrt rt<<1|1 #define lson rt<<1,l,mid #define rson rt<<1|1,mid+1,r const int maxn = 100010; int n,k,m; LL a[maxn],sum[maxn]; VI id[maxn]; struct Seg{ int l,r; bool operator < (const Seg &rhs) const{ return l < rhs.l; } }seg[maxn]; struct Tree{ int l,r; int cnt; int maxx,minx; }tree[maxn<<2]; void pushup(int rt){ tree[rt].maxx = max(tree[lrt].maxx,tree[rrt].maxx); tree[rt].minx = min(tree[lrt].minx,tree[rrt].minx); } void pushdown(int rt){ if(tree[rt].l == tree[rt].r) return ; if(tree[rt].cnt){ tree[lrt].maxx += tree[rt].cnt; tree[rrt].maxx += tree[rt].cnt; tree[lrt].minx += tree[rt].cnt; tree[rrt].minx += tree[rt].cnt; tree[lrt].cnt += tree[rt].cnt; tree[rrt].cnt += tree[rt].cnt; tree[rt].cnt = 0; } } void build(int rt,int l,int r){ tree[rt].l = l; tree[rt].r = r; tree[rt].cnt = 0; tree[rt].minx =tree[rt].maxx = 0; if(l == r) return; int mid = (l+r)>>1; build(lson); build(rson); } void modify(int rt,int l,int r,int val){ if(tree[rt].l == l && tree[rt].r == r){ tree[rt].cnt += val; tree[rt].maxx += val; tree[rt].minx += val; return; } pushdown(rt); int mid = (tree[rt].l+tree[rt].r)>>1; if(r <= mid) modify(lrt,l,r,val); else if(l > mid) modify(rrt,l,r,val); else {modify(lson,val);modify(rson,val);} pushup(rt); } int query(int rt){ pushdown(rt); if(tree[rt].maxx < k) return -1; if(tree[rt].minx >= k) return tree[rt].r; if(tree[rrt].maxx >= k) return query(rrt); return query(lrt); } void work(){ LL ans = 0; build(1,1,n); int x = 0; FOR(i,1,n+1){ //if(i == 4) //printf("hh\n"); while(x < m && seg[x].l <= i){ modify(1,i,seg[x].r,1); x ++; } int r = query(1); if(r >= i) ans = max(ans,sum[r]-sum[i-1]); } printf("%I64d\n",ans); } int main(){ //freopen("test.in","r",stdin); while(~scanf("%d%d%d",&n,&k,&m)){ sum[0] = 0; FOR(i,1,n+1) scanf("%I64d",&a[i]),sum[i] = sum[i-1]+a[i]; FOR(i,0,m) scanf("%d%d",&seg[i].l,&seg[i].r); sort(seg,seg+m); work(); } return 0; }
相关文章推荐
- C#数据结构之顺序表(SeqList)实例详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- 数据结构之Treap详解
- 用C语言举例讲解数据结构中的算法复杂度结与顺序表
- C#数据结构之堆栈(Stack)实例详解
- C#数据结构之双向链表(DbLinkList)实例详解
- JavaScript数据结构和算法之图和图算法
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- Java数据结构及算法实例:插入排序 Insertion Sort
- Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture
- java数据结构之java实现栈
- java数据结构之实现双向链表的示例
- Java数据结构及算法实例:选择排序 Selection Sort
- Java数据结构及算法实例:朴素字符匹配 Brute Force
- Java数据结构及算法实例:汉诺塔问题 Hanoi
- Java数据结构及算法实例:快速计算二进制数中1的个数(Fast Bit Counting)