Astar Round2B 1005 区间交 区间覆盖 线段树
2016-05-22 20:39
381 查看
题意
给出n个数和m个区间,要求在m个区间中找出k个区间,并让这k个区间的交集的和最大。思路
我们可以知道,如果一个区间满足被k个区间覆盖,那么其子区间也一定被
k个区间覆盖。那么我们可以用双指针的思想,如果
[l, r]区间满足条件,那么
l++, 否则
r++直到满足。即我们要知道如何快速的知道一个区间是否被k个区间覆盖。
对区间
[l, r]我们维护一个数组
sg,我们对所有的左端点比
l小的区间的右端点的位置
sg[*] + 1,然后统计
r后面的
sg[*]的和便是
[l, r]被覆盖的次数。因为sg是随前面的双指针动态更新的,所以用线段树维护。
code
#include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define MAXN (100000 + 5) int n, k, m; int l, r; long long a[MAXN], s[MAXN]; vector<int> v[MAXN]; struct sgtree { int m[MAXN << 2]; void push_up(int lr) { m[lr] = m[lr<<1] + m[lr<<1|1]; } void create(int l, int r, int lr) { if (l == r) { m[lr] = 0; return ; } int m = (l + r) / 2; create(l, m, lr<<1); create(m+1, r, lr<<1|1); push_up(lr); } void modif(int l, int r, int lr, int p) { if (l == r) { m[lr] ++; return ; } int m = (l + r) / 2; if (p <= m) modif(l, m, lr<<1, p); if (m < p) modif(m+1, r, lr<<1|1, p); push_up(lr); } int query(int l, int r, int lr, int L, int R) { if (l >= L && r <= R) { return m[lr]; } int m = (l + r) / 2; int res = 0; if (m >= L) res += query(l, m, lr<<1, L, R); if (m < R) res += query(m+1, r, lr<<1|1, L, R); return res; } }sg; void init () { for (int i=0; i<MAXN; i++) { v[i].clear(); } } bool check (int l, int r) { int rc = sg.query(1, n, 1, l ,r); if (rc >= k) return true; else return false; } int main () { while (scanf("%d%d%d", &n, &k, &m)!=EOF) { init(); for(int i=1;i<=n; i++) { scanf("%I64d", &a[i]); s[i] = s[i-1] + a[i]; } s[n+1] = s ; for (int i=0; i<m; i++) { scanf("%d%d", &l, &r); v[l].push_back(r); } int k = 0; sg.create(1, n, 1); long long ans = 0; for (int i=1; i<=n; i++) { for (int j=0; j<v[i].size(); j++) { sg.modif(1, n, 1, v[i][j]); } for (; check(k+1, n+1) && k <= n; k++); if (check(k, n)) { ans = max(ans, s[k] - s[i-1]); } } printf("%I64d\n", ans); } return 0; }
相关文章推荐
- vim 系统剪切板及 ubuntu 无法使用 vim 系统剪贴板(或 :reg 无+号寄存器)
- JVM 调优参数详解
- 膜拜acm大牛 虽然我不会这题,但是AC还是没有问题的~(转自hzwer)
- 2015-2016 ACM-ICPC, NEERC, Southern Subregional Contest, B. Layer Cake
- Oracle数据库—— PL/SQL基础编程
- L1-008. 求整数段和(C++)
- Linux内核module_param的使用
- 关于矩阵的题
- Glut处理鼠标事件
- ubuntu16.04的启动栏(Unity)方向更改
- Spanner vs. F1:谷歌两大数据管理利器的整体对比及关联
- IP地址的两种表示方法:整数和点分十进制`
- 机房收费—窗体嵌入窗体
- Matlab的高斯输入的PID仿真
- 利用python模拟登录
- 模态对话框和非模态对话框
- Hdu 5698 瞬间移动【组合+逆元】
- 递归再理解
- 在邓小平同志追悼大会上致悼词
- Qt WebView js交互(new) 支持ios android 平台