虽然看起来是求最短路,但因为条件的限制,可以转化为区间求最小值。

对于一条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 树状数组好题的更多相关文章

  1. HDU 1166 敌兵布阵(线段树/树状数组模板题)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  2. st表树状数组入门题单

    预备知识 st表(Sparse Table) 主要用来解决区间最值问题(RMQ)以及维护区间的各种性质(比如维护一段区间的最大公约数). 树状数组 单点更新 数组前缀和的查询 拓展:原数组是差分数组时 ...

  3. bzoj1103树状数组水题

    (卧槽,居然规定了修改的两点直接相连,亏我想半天) 非常水的题,用dfs序(而且不用重复,应该是直接规模为n的dfs序)+树状数组可以轻松水 收获:树状数组一遍A(没啥好骄傲的,那么简单的东西) #i ...

  4. UESTC 1584 Washi与Sonochi的约定【树状数组裸题+排序】

    题目链接:UESTC 1584 Washi与Sonochi的约定 题意:在二维平面上,某个点的ranked被定义为x坐标不大于其x坐标,且y坐标不大于其y坐标的怪物的数量.(不含其自身),要求输出n行 ...

  5. 敌兵布阵 HDU - 1166 (树状数组模板题,线段树模板题)

    思路:就是树状数组的模板题,利用的就是单点更新和区间求和是树状数组的强项时间复杂度为m*log(n) 没想到自己以前把这道题当线段树的单点更新刷了. 树状数组: #include<iostrea ...

  6. 树状数组训练题1:弱弱的战壕(vijos1066)

    题目链接:弱弱的战壕 这道题似乎是vijos上能找到的最简单的树状数组题了. 原来,我有一个错误的思想,我的设计是维护两个树状数组,一个是横坐标,一个是纵坐标,然后读入每个点的坐标,扔进对应的树状数组 ...

  7. 树状数组 简单题 cf 961E

    题目链接 : https://codeforces.com/problemset/problem/961/E One day Polycarp decided to rewatch his absol ...

  8. 【树状数组 思维题】luoguP3616 富金森林公园

    树状数组.差分.前缀和.离散化 题目描述 博艾的富金森林公园里有一个长长的富金山脉,山脉是由一块块巨石并列构成的,编号从1到N.每一个巨石有一个海拔高度.而这个山脉又在一个盆地中,盆地里可能会积水,积 ...

  9. Lightoj 1112 - Curious Robin Hood 【单点改动 + 单点、 区间查询】【树状数组 水题】

    1112 - Curious Robin Hood PDF (English) Statistics Forum Time Limit: 1 second(s) Memory Limit: 64 MB ...

随机推荐

  1. Rich feature hierarchies for accurate object detection and semantic segmentation(RCNN)

    https://zhuanlan.zhihu.com/p/23006190?refer=xiaoleimlnote http://blog.csdn.net/bea_tree/article/deta ...

  2. Windows核心编程-作业

    原文链接:http://zhujiangtao.com/?p=983 作业 作业 一个简单例程 CreateJobObject 创建作业 作业限制和 SetInformationJobObject A ...

  3. Java面试不得不知的程序(二)

    [程序1]   题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 斐波那契数列:前面相邻两项之和,构 ...

  4. ES6初识-模块化

    export let A=123; export function test(){ console.log('test'); } export class Hello(){ test(){ conso ...

  5. 触发ionic弹窗区域外的方法

    最近项目需要在页面弹窗的时候需要点击弹窗区域外的地方,其实也就是点击页面HTML就可以关闭弹窗, 首先在controller通过js获取到html的dom节点,然后绑定点击事件,话不多说上代码:   ...

  6. Scott Young-《如何高效学习》

    1.如果你只用一种方式了解某样事物,那么你就没有真正了解它.事情真正含义的秘密取决于我们如何将其与我们所了解的其他事情相联系.很好联系的内容可使你将想法融于脑中,从各种角度看问题,直至你找到合适自己的 ...

  7. 【杂题总汇】UVa-1627 Team them up!

    [UVa-1627] Team them up! 借鉴了一下hahalidaxin的博客……了解了思路,但是莫名Wa了:最后再找了一篇dwtfukgv的博客才做出来

  8. lincode 680 Split String

    Split String    描述 笔记 数据 评测 Give a string, you can choose to split the string after one character or ...

  9. mysql 自增主键为什么不是连续的?

    由于自增主键可以让主键索引尽量地保持递增顺序插入,避免了页分裂,因此索引更紧凑 MyISAM 引擎的自增值保存在数据文件中 nnoDB 引擎的自增值,其实是保存在了内存里,并且到了 MySQL 8.0 ...

  10. 懒下载软件,一行代码连接wifi^_^

    按键盘的windows+R,输入cmd,回车键 设置语句netsh wlan set hostednetwork mode=allow ssid=user key=possword 按回车键 启动语句 ...