51Nod-1672-区间交
来源:互联网 发布:在淘宝买家具靠谱吗 编辑:程序博客网 时间:2024/06/04 19:11
ACM模版
描述
题解
首先排序右端点从小到大,然后枚举右端点(保证所枚举的那个端点最少有k个区间可以覆盖)作为所求的交区间的右端点,这时候需要求出交区间的左端点,我们可以知道,右端点确定下,如果左端点越靠左,这个区间的范围约大。为了保证所交区间有k个,我们需要找到第k小的左端点,为了保证我枚举的右端点肯定是交区间的右端点,我们必须边枚举,边单点更新左端点。
具体的代码实现还是有很多需要注意的地方(注释写得很清晰),有一些代码段不是十分容易理解,另外,排序也可以对左端点进行排序,也可以从大到小排序,不同的排序,后边的处理手段会有一些区别,但是整体是一样的。
代码
#include <stdio.h>#include <stdlib.h>//#pragma GCC optimize("02")#define MAXSIZE 100005#define MID (L + R) >> 1#define LSON tag * 2, L, MID#define RSON tag * 2 + 1, (MID) + 1, R#define MAX(a, b) a > b ? a : btypedef long long LL;LL A, ans;LL sum[MAXSIZE] = {0}; //前缀和typedef struct{ int left; int right;}route;route rou[MAXSIZE];struct seg{ int cover;}segs[MAXSIZE * 4];//输入LLvoid scanfDiyLL(LL *ret){ char c; *ret = 0; while((c = getchar()) < '0' || c > '9'); while(c >= '0' && c <= '9') *ret = (*ret) * 10 + (c - '0'), c = getchar(); return ;}//输入intvoid scanfDiyInt(int *ret){ char c; *ret = 0; while((c = getchar()) < '0' || c > '9'); while(c >= '0' && c <= '9') *ret = (*ret) * 10 + (c - '0'), c = getchar(); return ;}int cmp(const void *a, const void *b){ route *aa = (route *)a; route *bb = (route *)b; if (aa->right != bb->right) { return aa->right > bb->right ? 1 : -1; } return 0;}void pushUp(int tag){ segs[tag].cover = segs[tag * 2].cover + segs[tag * 2 + 1].cover; return ;}void buildTree(int tag, int L, int R){ if (L == R) { segs[tag].cover = 0; //建树时初始化重叠次数为0 return ; } buildTree(LSON); buildTree(RSON); pushUp(tag); return ;}//查找并更新void upDate(int tag, int L, int R, int id){ if (L == R) { segs[tag].cover++; return ; } if (id <= MID) { upDate(LSON, id); } else { upDate(RSON, id); } pushUp(tag); return ;}int query(int tag, int L, int R, int k){ if (L == R) { return L; } if (k <= segs[tag * 2].cover) //左边为最高优先选择 { return query(LSON, k); } else { return query(RSON, k - segs[tag * 2].cover); //左边不足,取左边,剩余不足的取右边 }}int main(int argc, const char * argv[]){ int n, k, m; while (~scanf("%d %d %d", &n, &k, &m)) { buildTree(1, 1, n); for (int i = 1; i <= n; i++) { scanfDiyLL(&A); sum[i] = sum[i - 1] + A; } for (int i = 1; i <= m; i++) { scanfDiyInt(&rou[i].left); scanfDiyInt(&rou[i].right); } qsort(rou + 1, m, sizeof(rou[0]), cmp); //右端点由小到大排序// for (int i = 1; i <= m; i++)// {// printf("%d %d\n", rou[i].begin, rou[i].end);// } for (int i = m - k + 1; i <= m; i++) //这一部分右端点可以肯定不会是交区间右端点 { upDate(1, 1, n, rou[i].left); } ans = 0; for (int i = m - k + 1; i >= 1; i--) { int l = query(1, 1, n, k); if (l <= rou[i].right) //以rou[i].end为右端点 { ans = MAX(ans, sum[rou[i].right] - sum[l - 1]); } upDate(1, 1, n, rou[i - 1].left); //继续加区间端点 } printf("%lld\n", ans); } return 0;}
0 0
- 51Nod-1672-区间交
- 51nod-1672 区间交
- 51NOD 1672 区间交
- 51nod 1672 区间交
- 51nod 1672 区间交
- 51nod 1672 区间交
- 51Nod 1672 区间交
- 51Nod-1672-区间交
- 51NOD 1672 区间交 线段树
- 51 nod 1672 区间交(枚举 贪心)
- 51nod 1672 区间交(贪心)
- 51nod 1627 区间交
- 【51Nod】1672 - 区间交(线段树 & 贪心)
- 51nod 1672 区间交【线段树、multiset】
- 51nod 1672 区间交 (经典贪心)
- 51nod 1672-区间交(线段树)
- 51nod 1672 区间交【线段树】【贪心】
- 51 nod 区间交 (优先队列)
- (二)maven简介
- clone 某指定远程分支
- Linux中查找命令总结
- Window上git bash命令行中文乱码问题解决方案
- Scrum敏捷实践: Daily Scrum Meeting
- 51Nod-1672-区间交
- 【干货】产品经理FM会客厅之需求分析
- C#入门7.8——数组合并与拆分
- ionic2@beta 生命周期
- spring-xfire初学
- 2016 最新开发者账号 · 邓白氏申请申请流
- 重点指针
- 计算几何POJ 2826 接水WA哭
- ionic 路由传参小结