ZOJ 3724 Delivery 树状数组好题
虽然看起来是求最短路,但因为条件的限制,可以转化为区间求最小值。
对于一条small path [a, b],假设它的长度是len,它对区间[a, b]的影响就是:len-( sum[b]-sum[a-1] );(使区间[a,b]的原有长度变长或者变短,变长没有意义,所以我们只考虑变短的情况),因为只能选择一条small path,所以对于每个查询[u, v],就是要选择在区间[u, v]内,让原有长度减少最多的那条small path,即求区间最小值。
离线处理:
将查询和small path放在一起排序,按u从大到小,v从小到大排。
因为我们要从后往前扫,对于每个查询[u, v],我们应当保证在本查询之前的所有[u', v']已经更新进去。
当u < v时,u < u', v' < v,树状数组minv[i]中记录的是以i为区间右端点的所有small path中len-( sum[b]-sum[a-1] )的最小值,答案为[u, v]的区间和+该最小值。
当u > v时,v' < v, u < u',树状数组minv[i]中记录的是从i点走回i点(走了一个圈)的最小值。答案为最小值减去[u, v]的区间和。
------------------------以下吐槽--------------------------
本来以为不是很难的一道树状数组,结果折腾了一晚上……主要是对查询中u>v的情况处理总是各种出问题,之前我是想把1-N扩大一倍变成1-2N,这样对于查询中u>v的情况就可以转换成查询[ u, N+v ]。事实证明这样转换是不对的……画画图看看就知道为啥了。
然后我又想关于N轴对称把点翻转过去,还是1-2N,只不过把查询变成了[ u, 2N - v ]。还是各种出错orz……
最后实在没办法,老老实实的分开处理了……
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm> #define LL long long int using namespace std; const int MAXN = << ;
const int INF = ;
long long int one = ; LL sum[MAXN]; //区间和
LL minv[MAXN];
LL ans[]; int N, M; struct node
{
int l, r;
LL val;
int id;
}; node D[ MAXN << ]; int lowbit( int x )
{
return x & ( -x );
} void Add( int x, LL val )
{
while ( x <= N )
{
minv[x] = min( minv[x], val );
x += lowbit(x);
}
return;
} LL Query( int x )
{
LL res = one << ;
while ( x > )
{
res = min( res, minv[x] );
x -= lowbit(x);
}
return res;
} bool cmp( node a, node b )
{
if ( a.l != b.l ) return a.l > b.l;
if ( a.r != b.r ) return a.r < b.r;
return a.id < b.id;
} int main()
{
//freopen( "in.txt", "r", stdin );
//freopen( "out.txt", "w", stdout );
while ( scanf( "%d%d", &N, &M ) == )
{
memset( minv, , sizeof(minv) ); sum[] = ;
for ( int i = ; i < N; ++i )
{
scanf( "%I64d", &sum[i] );
sum[i] += sum[i - ];
}
sum[N] = INF; int cnt = ;
for ( int i = ; i < M; ++i )
{
int a, b, c;
scanf( "%d%d%d", &a, &b, &c );
LL tmp;
if ( a > b )
tmp = (LL)c + sum[a - ] - sum[b - ];
else
tmp = (LL)c - sum[b - ] + sum[a - ];
D[cnt].l = a;
D[cnt].r = b;
D[cnt].val = tmp;
D[cnt].id = -;
++cnt;
} int Q;
scanf( "%d", &Q );
for ( int i = ; i < Q; ++i )
{
int a, b;
scanf( "%d%d", &a, &b );
D[cnt].id = i;
D[cnt].val = ;
D[cnt].l = a;
D[cnt].r = b;
++cnt;
} memset( ans, , sizeof(ans) );//之前少了这个,一直WA…好像上组数据会影响到下组数据中u=v的情况
sort( D, D + cnt, cmp ); for ( int i = ; i < cnt; ++i )
{
if ( D[i].l < D[i].r )
{
Add( D[i].r, D[i].val );
if ( D[i].id != - )
ans[ D[i].id ] = sum[ D[i].r - ] - sum[ D[i].l - ] + Query( D[i].r );
}
} for ( int i = ; i <= N; ++i )
minv[i] = one << ; for ( int i = ; i < cnt; ++i )
{
if ( D[i].l > D[i].r )
{
if ( D[i].id == - ) Add( D[i].r, D[i].val );
if ( D[i].id != - )
ans[ D[i].id ] = Query( D[i].r ) - sum[ D[i].l - ] + sum[ D[i].r - ];
}
} for ( int i = ; i < Q; ++i )
printf( "%d\n", (int)ans[i] );
}
return ;
}
ZOJ 3724 Delivery 树状数组好题的更多相关文章
- HDU 1166 敌兵布阵(线段树/树状数组模板题)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- st表树状数组入门题单
预备知识 st表(Sparse Table) 主要用来解决区间最值问题(RMQ)以及维护区间的各种性质(比如维护一段区间的最大公约数). 树状数组 单点更新 数组前缀和的查询 拓展:原数组是差分数组时 ...
- bzoj1103树状数组水题
(卧槽,居然规定了修改的两点直接相连,亏我想半天) 非常水的题,用dfs序(而且不用重复,应该是直接规模为n的dfs序)+树状数组可以轻松水 收获:树状数组一遍A(没啥好骄傲的,那么简单的东西) #i ...
- UESTC 1584 Washi与Sonochi的约定【树状数组裸题+排序】
题目链接:UESTC 1584 Washi与Sonochi的约定 题意:在二维平面上,某个点的ranked被定义为x坐标不大于其x坐标,且y坐标不大于其y坐标的怪物的数量.(不含其自身),要求输出n行 ...
- 敌兵布阵 HDU - 1166 (树状数组模板题,线段树模板题)
思路:就是树状数组的模板题,利用的就是单点更新和区间求和是树状数组的强项时间复杂度为m*log(n) 没想到自己以前把这道题当线段树的单点更新刷了. 树状数组: #include<iostrea ...
- 树状数组训练题1:弱弱的战壕(vijos1066)
题目链接:弱弱的战壕 这道题似乎是vijos上能找到的最简单的树状数组题了. 原来,我有一个错误的思想,我的设计是维护两个树状数组,一个是横坐标,一个是纵坐标,然后读入每个点的坐标,扔进对应的树状数组 ...
- 树状数组 简单题 cf 961E
题目链接 : https://codeforces.com/problemset/problem/961/E One day Polycarp decided to rewatch his absol ...
- 【树状数组 思维题】luoguP3616 富金森林公园
树状数组.差分.前缀和.离散化 题目描述 博艾的富金森林公园里有一个长长的富金山脉,山脉是由一块块巨石并列构成的,编号从1到N.每一个巨石有一个海拔高度.而这个山脉又在一个盆地中,盆地里可能会积水,积 ...
- Lightoj 1112 - Curious Robin Hood 【单点改动 + 单点、 区间查询】【树状数组 水题】
1112 - Curious Robin Hood PDF (English) Statistics Forum Time Limit: 1 second(s) Memory Limit: 64 MB ...
随机推荐
- 旧文备份:rtlinux安装手册
前段时间接触了几天RTLinux,折腾了好几天才总算把它安装上,得益于Prof. Chang-Gun Lee的安装建议,觉得该文档可能会对准备尝试安装RTLinux的朋友们有帮助,本人英语很烂,也比较 ...
- JAVAWEB开发中过滤器的概述及使用
1.什么是过滤器? 过滤器是向WEB应用程序的请求和响应添加功能的WEB服务组件 2.过滤器的作用 1)可以统一的集中处理请求和响应 2)可以实现对请求数据的过滤 3.过滤器的工作方式 4.使用场合 ...
- JS实现Promise原理
promise是用来解决Js中的异步问题的,js中所有的异步可从callback → promise → generator + co = async + await 其实所有的都是callback的 ...
- v-if
vue中通过v-if,v-else-if,v-else的对应的Boolean值来操作元素在dom中是否移除. 这里就以单纯的true,false来模拟一下.注:标签属性去出来的值为string类型. ...
- HTTP:地址栏输入url到显示页面的步骤
在浏览器地址栏输入URL 浏览器查看缓存,如果请求资源在缓存中并且新鲜,跳转到转码步骤 如果资源未缓存,发起新请求 如果已缓存,检验是否足够新鲜,足够新鲜直接提供给客户端,否则与服务器进行验证. 检验 ...
- 小程序weapp的状态管理 Wenaox
Wenaox wechat state management 特点 支持中间件 中大型项目可多个 contro 区分模块 asyncs 自带 loading 轻量.性能好 安装 npm i -S we ...
- MySQL时间戳、时间
MySQL中: now():获取当前时间:例:SELECT now(); // 结果:2018-07-03 13:40:14 unix_timestamp():将时间转换为时间戳:例: SELECT ...
- 前端之jquery函数库
jquery介绍 jQuery是目前使用最广泛的javascript函数库.据统计,全世界排名前100万的网站,有46%使用jQuery,远远超过其他库.微软公司甚至把jQuery作为他们的官方库. ...
- SSH 登录时出现如下错误:No supported key exchange algorithms
https://help.aliyun.com/knowledge_detail/41486.html
- JS下载文件常用的方式
下载附件(image,doc,docx, excel,zip,pdf),应该是实际工作中经常遇到一个问题:这里使用过几种方式分享出来仅供参考; 初次写可能存在问题,有问题望指出 主要了解的几个知识 ...