题意:给你n个区间,从中选择m个,使得它们有交,且最长与最短区间的差值最小。

解:这道题我想了好多的,nlog²n错的,nlogn错的,最后终于想出nlogn的了......

把区间按照长度排序,然后依次在线段树上加。

如果某一次等于m了,那么一个一个删,删到小于m的时候,更新答案。

证明:那些之前的区间如果想要成为答案,那么必须是和比当前这个还靠前的区间来组成。

这样的话当到这一个时,之前的要么被计算,要么不会更优。故可以删掉。

 #include <cstdio>
#include <algorithm> const int N = , INF = 0x3f3f3f3f; int sum[N << ], large[N << ], tag[N << ], X[N << ]; struct ITV {
int r, l, len;
inline bool operator <(const ITV &w) const {
return len < w.len;
}
}a[N]; inline void pushup(int o) {
int ls = o << ;
int rs = ls | ;
sum[o] = sum[ls] + sum[rs];
large[o] = std::max(large[ls], large[rs]);
return;
} inline void pushdown(int l, int r, int o) {
if(tag[o]) {
int ls = o << ;
int rs = ls | ;
int mid = (l + r) >> ;
tag[ls] += tag[o];
tag[rs] += tag[o];
sum[ls] += (mid - l + ) * tag[o];
sum[rs] += (r - mid) * tag[o];
large[ls] += tag[o];
large[rs] += tag[o];
tag[o] = ;
}
return;
} inline void add(int L, int R, int v, int l, int r, int o) {
if(L <= l && r <= R) {
tag[o] += v;
sum[o] += v * (r - l + );
large[o] += v;
return;
}
pushdown(l, r, o);
int mid = (l + r) >> ;
if(L <= mid) {
add(L, R, v, l, mid, o << );
}
if(mid < R) {
add(L, R, v, mid + , r, o << | );
}
pushup(o);
return;
} int main() { int n, m;
scanf("%d%d", &n, &m);
for(int i = ; i <= n; i++) {
scanf("%d%d", &a[i].l, &a[i].r);
a[i].len = a[i].r - a[i].l;
X[i << ] = a[i].l;
X[(i << ) - ] = a[i].r;
}
std::sort(a + , a + n + );
std::sort(X + , X + (n << ) + );
int t = std::unique(X + , X + (n << ) + ) - X - ;
int j = , ans = INF;
for(int i = ; i <= n; i++) {
a[i].l = std::lower_bound(X + , X + t + , a[i].l) - X;
a[i].r = std::lower_bound(X + , X + t + , a[i].r) - X;
add(a[i].l, a[i].r, , , t, );
while(large[] >= m) {
add(a[j].l, a[j].r, -, , t, );
//printf("large[1] = %d ans = %d \n i = %d j = %d \n", large[1], ans, i, j);
ans = std::min(ans, a[i].len - a[j].len);
j++;
}
}
if(ans == INF) {
ans = -;
}
printf("%d\n", ans);
return ;
}

AC代码

这个sum其实是不必要的。

然后我还用动态开点写了一发......被卡空间了。

 #include <cstdio>
#include <algorithm> const int N = , INF = 0x3f3f3f3f; int large[N * ], tag[N * ], root, ls[N * ], rs[N * ], tot; struct ITV {
int r, l, len;
inline bool operator <(const ITV &w) const {
return len < w.len;
}
}a[N]; inline void pushup(int o) {
large[o] = std::max(large[ls[o]], large[rs[o]]);
return;
} inline void pushdown(int l, int r, int o) {
if(tag[o]) {
int mid = (l + r) >> ;
if(ls[o]) {
large[ls[o]] += tag[o];
tag[ls[o]] += tag[o];
}
if(rs[o]) {
large[rs[o]] += tag[o];
tag[rs[o]] += tag[o];
}
tag[o] = ;
}
return;
} inline void add(int L, int R, int v, int l, int r, int &o) {
if(!o) {
o = ++tot;
}
if(L <= l && r <= R) {
tag[o] += v;
large[o] += v;
return;
}
if(!ls[o]) {
ls[o] = ++tot;
}
if(!rs[o]) {
rs[o] = ++tot;
}
pushdown(l, r, o);
int mid = (l + r) >> ;
if(L <= mid) {
add(L, R, v, l, mid, ls[o]);
}
if(mid < R) {
add(L, R, v, mid + , r, rs[o]);
}
pushup(o);
return;
} int main() { int n, m, lm = ;
scanf("%d%d", &n, &m);
for(int i = ; i <= n; i++) {
scanf("%d%d", &a[i].l, &a[i].r);
a[i].len = a[i].r - a[i].l;
lm = std::max(lm, a[i].r);
}
std::sort(a + , a + n + );
int j = , ans = INF;
for(int i = ; i <= n; i++) {
add(a[i].l, a[i].r, , , lm, root);
while(large[] >= m) {
add(a[j].l, a[j].r, -, , lm, root);
//printf("large[1] = %d ans = %d \n i = %d j = %d \n", large[1], ans, i, j);
ans = std::min(ans, a[i].len - a[j].len);
j++;
}
}
if(ans == INF) {
ans = -;
}
printf("%d\n", ans);
return ;
}

95分动态开点

最新文章

  1. Windows 10开机的秘密在哪里
  2. iOS开发之蓝牙通讯
  3. javascript的三个组成部分
  4. python中的for循环
  5. 菜鸟学习Spring——60s配置XML方法实现简单AOP
  6. 如何使用 Docker 部署一个基于 Play Framework 的 Scala Web 应用?
  7. Redis的Time Event与File Event的微妙关系
  8. [c#]asp.net开发微信公众平台(6)阶段总结、服务搭建、接入
  9. linux下实现ftp匿名用户的上传和下载文件功能
  10. 测试驱动开发实践3————testSave之新增用户
  11. ORA-28000错误的原因及解决办法
  12. EmWin 字体相关函数
  13. idea 2017破解方法
  14. [Windows Azure] Building worker role B (email sender) for the Windows Azure Email Service application - 5 of 5.
  15. 如何使用Javascript XSLT 处理XML文件(支持Firefox)
  16. Deep Residual Learning for Image Recognition(残差网络)
  17. 工作流JBPM_day02:3-预定义的活动1_4-预定义的活动2+在图片上高亮显示正在执行的上活动
  18. Java中的String和StringBuffer
  19. [LeetCode]Swap Nodes in Pairs题解
  20. 奇异值分解(SVD)原理详解及推导(转载)

热门文章

  1. Jenkins配置权限管理
  2. 二叉搜索树的第k个节点
  3. pring @Configuration 和 @Component 区别
  4. Navicat 远程连接Docker容器中的mysql 报错:1251 - Client does not support authentication protocol 解决办法。
  5. python之路--类与类之间的关系
  6. dentry path_lookat dput
  7. 阿里云ECS服务器,CentOS 7.4配置jdk+tomcat+mysql
  8. 前端框架framework和库library的一点区别和记录
  9. ES6字符串操作
  10. AMD直奔5nm!这一步棋下得妙