首页 > 代码库 > asdasd
asdasd
/* 线段树区间操作GSS 一段长的区间的 GSS 有三种情况: 1 完全在左子区间 2 完全在右子区间 3 横跨左右区间 前两种情况可使用子区间的 GSS,但如何处理第三种情况? 注意到可以把区间拆成两部分,这两部分是不相关的。 所以需要维护一个区间的“最大左子段和”和“最大右子段和”。 gss = MAX{l.gss,r.gss,l.rgss + r.lgss} 由 GSS 一直推下来,对于每个节点,一共需要设计4个状态。 1 GSS:最大子段和 2 LGSS:最大左子段和 3 RGSS:最大右子段和 4 SUM:整段和 */ #include <cstdio> #define Max 202090 inline long long max (long long a, long long b) { return a > b ? a : b; } void read (long long &now) { now = 0; register char word = getchar (); bool flag = false; while (word < ‘0‘ || word > ‘9‘) { if (word == ‘-‘) flag = true; word = getchar (); } while (word >= ‘0‘ && word <= ‘9‘) { now = now * 10 + word - ‘0‘; word = getchar (); } if (flag) now = -now; } struct Segment_Tree_Type { struct Segment_Tree { long long l; long long r; long long Mid; long long Sum; long long Max_Suffix; long long Max_Prefix; long long Max_Sum; }; Segment_Tree tree[Max << 3]; void Build (long long l, long long r, long long now) { tree[now].l = l; tree[now].r = r; if (l == r) { read (tree[now].Sum); tree[now].Max_Sum = tree[now].Sum; tree[now].Max_Suffix = tree[now].Sum; tree[now].Max_Prefix = tree[now].Sum; return ; } tree[now].Mid = (l + r) >> 1; Build (l, tree[now].Mid, now << 1); Build (tree[now].Mid + 1, r, now << 1 | 1); tree[now].Max_Prefix = max (tree[now << 1].Max_Prefix, tree[now << 1].Sum + tree[now << 1 | 1].Max_Prefix); tree[now].Max_Suffix = max (tree[now << 1 | 1].Max_Suffix, tree[now << 1 | 1].Sum + tree[now << 1].Max_Suffix); tree[now].Max_Sum = max (tree[now << 1].Max_Suffix + tree[now << 1 | 1].Max_Prefix, max (tree[now << 1].Max_Sum, tree[now << 1 | 1].Max_Sum)); tree[now].Sum = tree[now << 1].Sum + tree[now << 1 | 1].Sum; } Segment_Tree Query_section (long long l, long long r, long long now) { Segment_Tree Suffix, Prefix; Segment_Tree res; if (tree[now].l == l && tree[now].r == r) return tree[now]; if (r <= tree[now].Mid) return Query_section (l, r, now << 1); else if (l > tree[now].Mid) return Query_section (l, r, now << 1 | 1); else { Prefix = Query_section (l, tree[now].Mid, now << 1); Suffix = Query_section (tree[now].Mid + 1, r, now << 1 | 1); res.Max_Prefix = max (Prefix.Max_Prefix, Prefix.Sum + Suffix.Max_Prefix); res.Max_Suffix = max (Suffix.Max_Suffix, Suffix.Sum + Prefix.Max_Suffix); res.Max_Sum = max (Prefix.Max_Suffix + Suffix.Max_Prefix, max (Prefix.Max_Sum, Suffix.Max_Sum)); } return res; } }; Segment_Tree_Type Tree; long long N; int main (int argc, char *argv[]) { read (N); Tree.Build (1, N, 1); read (N); long long x, y; while (N--) { read (x); read (y); printf ("%lld\n", Tree.Query_section (x, y, 1).Max_Sum); } return 0; }
asdasd
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。