博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
uva1400线段树
阅读量:4320 次
发布时间:2019-06-06

本文共 3497 字,大约阅读时间需要 11 分钟。

  题意:在l,r区间找到 最靠近左边的和最大区间。

要理清思路写。简单区间合并。查找要麻烦点,三个查找函数,分别是向左范围内最大连续,向右范围内最大连续,整体最大连续。

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;typedef long long LL;#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1const int maxn = 555555;const LL INF = 1844674407370955161LL;LL sum[maxn << 2], Max[maxn << 2], rmax[maxn << 2], lmax[maxn << 2];int rl[maxn << 2], lr[maxn << 2], rpos[maxn << 2], lpos[maxn << 2], tfr[maxn << 2], tfl[maxn << 2];int fl[maxn << 2], fr[maxn << 2];void up(int l, int r, int rt){ sum[rt] = sum[rt << 1] + sum[rt << 1 | 1]; lmax[rt] = lmax[rt << 1]; rmax[rt] = rmax[rt << 1 | 1]; lr[rt] = lr[rt << 1]; rl[rt] = rl[rt << 1 | 1]; LL k = rmax[rt << 1] + lmax[rt << 1 | 1]; if (sum[rt << 1] + lmax[rt << 1 | 1] > lmax[rt]){ lmax[rt] = sum[rt << 1] + lmax[rt << 1 | 1]; lr[rt] = lr[rt << 1 | 1]; } if (sum[rt << 1 | 1] + rmax[rt << 1] > rmax[rt << 1 | 1]){ rmax[rt] = sum[rt << 1 | 1] + rmax[rt << 1]; rl[rt] = rl[rt << 1]; } if (lmax[rt] >= k&&lmax[rt] >= rmax[rt]){ Max[rt] = lmax[rt]; lpos[rt] = l; rpos[rt] = lr[rt]; } else if (k >= lmax[rt] && k >= rmax[rt]){ Max[rt] = k, lpos[rt] = rl[rt << 1], rpos[rt] = lr[rt << 1 | 1]; } else Max[rt] = rmax[rt], lpos[rt] = rl[rt], rpos[rt] = r;}void build(int l, int r, int rt){ if (l == r){ LL t; scanf("%lld",&t); sum[rt] = Max[rt] = lmax[rt] = rmax[rt] = t; lpos[rt]=rpos[rt]=lr[rt] = rl[rt] = l; return; } int mid = (l + r) >> 1; build(lson); build(rson); up(l, r, rt);}LL asks(int L, int R, int l, int r, int rt){ if (L <= l&&r <= R) return sum[rt]; int mid = (l + r) >> 1; LL ans = 0; if (L <= mid) ans += asks(L, R, lson); if (R > mid) ans += asks(L, R, rson); return ans;}LL askl(int L, int R, int l, int r, int rt){ if (L <= l&&r <= R) { tfr[rt] = lr[rt]; return lmax[rt]; } int mid = (l + r) >> 1; LL ans1 = -INF; LL ans2 = -INF; if (L <= mid) ans1 = askl(L, R, lson); if (R > mid) ans2 = askl(L, R, rson); LL k = asks(L, R, lson); if (ans1 >= ans2 + k){ tfr[rt] = tfr[rt << 1]; return ans1; } else { tfr[rt] = tfr[rt << 1 | 1]; return ans2 + k; }}LL askr(int L, int R, int l, int r, int rt){ if (L <= l&&r <= R){ tfl[rt] = rl[rt]; return rmax[rt]; } int mid = (l + r) >> 1; LL ans1 = -INF; LL ans2 = -INF; if (L <= mid) ans1 = askr(L, R, lson); if (R > mid) ans2 = askr(L, R, rson); LL k = asks(L, R, rson); if (k + ans1 >= ans2){ tfl[rt] = tfl[rt << 1]; return k + ans1; } else{ tfl[rt] = tfl[rt << 1 | 1]; return ans2; }}LL ask(int L, int R, int l, int r, int rt){ if (L <= l&&r <= R){ fl[rt] = lpos[rt]; fr[rt] = rpos[rt]; return Max[rt]; } int mid = (l + r) >> 1; LL ans = -INF; if (L <= mid){ LL k = ask(L, R, lson); if (k > ans){ ans = k; fl[rt] = fl[rt << 1]; fr[rt] = fr[rt << 1]; } } if (L <= mid&&R > mid){ LL ans1 = askl(mid+1, R, rson); LL ans2 = askr(L, mid, lson); int tl = tfl[rt<<1]; int tr = tfr[rt<<1|1]; if (ans1 + ans2 > ans) { ans = ans1 + ans2; fl[rt] = tl; fr[rt] = tr; } } if (R > mid){ LL k = ask(L, R, rson); if (k > ans){ ans = k; fl[rt] = fl[rt << 1 | 1]; fr[rt] = fr[rt << 1 | 1]; } } return ans;}int main(){ int n, m, l, r; int Icase = 0; while (cin >> n >> m){ build(1, n, 1); printf("Case %d:\n", ++Icase); for (int i = 0; i < m; i++){ scanf("%d%d", &l, &r); int t = ask(l, r, 1, n, 1); printf("%d %d\n", fl[1], fr[1]); } } return 0;}

 

转载于:https://www.cnblogs.com/yigexigua/p/4024100.html

你可能感兴趣的文章
PyQT的安装和配置
查看>>
从 docker 到 runC
查看>>
守护进程
查看>>
php数组
查看>>
Linux 防火墙
查看>>
互联网金融P2P主业务场景自动化测试
查看>>
My third day of OpenCV
查看>>
Android的View和ViewGroup分析
查看>>
echarts.js中的图表大小自适应
查看>>
Delphi的FIFO实现
查看>>
牛客网暑期ACM多校训练营(第一场) - J Different Integers(线段数组or莫队)
查看>>
(转)AS3 面相对象 高级话题
查看>>
Missile
查看>>
关于kindedit和 Uedit后者兼容前者
查看>>
微软BI 之SSIS 系列 - 利用 SSIS 模板快速开发 SSIS Package
查看>>
eclipse中使用git上传到githup,报401 Authorization Required
查看>>
基于Golang打造一款开源的WAF网关
查看>>
POJ 2955 Brackets
查看>>
Python: execute an external program (zz)
查看>>
在T-SQL语句中访问远程数据库(openrowset/opendatasource/openquery)
查看>>