SPOJ GSS系列 解题报告

这个系列总共有7道题,目前只做了3道,gss2比较难,gss4是暴力修改,树状数组维护,还没写,gss6和gss7还不在能力范围内。

SPOJ_1043 GSS1

题意:给定长度不超过5万的序列,M次查询(貌似没给大小?。。),查询所给区间内的最大子段和。

做法:线段树。维护区间和sum,区间可以得到的最大值smax,从区间最左边开始的最大和lmax和右边开始的rmax,然后就可以了。具体更新还是看代码吧。比较巧妙的在于,把query函数的类型设为线段树的节点类型,这样就可以把它的子区间用update(即pushup)的操作来合并,否则query函数会很难写。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 int n, m;
 5 int a[50100];
 6 struct tree{
 7     int sum, lmax, rmax, smax;
 8 } t[50010 << 2];
 9
10 int max(int a, int b)
11 {
12     return a>b?a:b;
13 }
14 void update(tree &x, tree lson, tree rson)
15 {
16     x.sum = lson.sum + rson.sum;
17     x.lmax = max(lson.lmax, lson.sum+rson.lmax);
18     x.rmax = max(rson.rmax, rson.sum+lson.rmax);
19     int tmp = max(x.lmax, x.rmax);
20     tmp = max(tmp, x.sum);
21     tmp = max(tmp, lson.smax);
22     tmp = max(tmp, rson.smax);
23     tmp = max(tmp, lson.rmax+rson.lmax);
24     x.smax = tmp;
25     //x.smax = max(max(x.sum, max(x.lmax, x.rmax)), max(max((lson.smax, rson.smax), (lson.rmax+rson.lmax))));
26 }
27 void build(int x, int l, int r)
28 {
29     if (l == r){
30         t[x].sum = t[x].lmax = t[x].rmax = t[x].smax = a[l];
31         return;
32     }
33     int mid = l + r >> 1, lson = x<<1, rson = x<<1|1;
34     build(lson, l, mid);
35     build(rson, mid+1, r);
36     update(t[x], t[lson], t[rson]);
37 }
38 tree query(int s, int e, int x, int l, int r)
39 {
40     if (s <= l && r <= e){
41     //if (s <= l && r <= e){
42         return t[x];
43     }
44     int mid = l + r >> 1;
45     if (e <= mid) return query(s, e, x<<1, l, mid);
46     if (s > mid) return query(s, e, x<<1|1, mid+1, r);
47     tree p, q, ans;
48     p = query(s, mid, x<<1, l, mid);
49     q = query(mid+1, e, x<<1|1, mid+1, r);
50     update(ans, p, q);
51     return ans;
52 }
53 int main()
54 {
55     scanf("%d", &n);
56     for (int i = 1; i <= n; i++)
57         scanf("%d", &a[i]);
58     build(1, 1, n);
59
60 //    for (int i = 1; i <= 10; i++)
61 //        printf("%d %d %d %d %d\n", i, t[i].sum, t[i].lmax, t[i].rmax, t[i].smax);
62
63     scanf("%d", &m);
64     int x, y;
65     for (int i = 0; i < m; i++){
66         scanf("%d %d", &x, &y);
67         printf("%d\n", query(x, y, 1, 1, n).smax);
68     }
69     return 0;
70 }

SPOJ_1557 GSS2

SPOJ_1716 GSS3

分析:相比gss1,多了一个单点修改的操作。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 int n, m;
 5 int a[50100];
 6 struct tree{
 7     int sum, lmax, rmax, smax;
 8 } t[50010 << 2];
 9
10 int max(int a, int b)
11 {
12     return a>b?a:b;
13 }
14 void pushup(tree &x, tree lson, tree rson)
15 {
16     x.sum = lson.sum + rson.sum;
17     x.lmax = max(lson.lmax, lson.sum+rson.lmax);
18     x.rmax = max(rson.rmax, rson.sum+lson.rmax);
19 /*    int tmp = max(x.lmax, x.rmax);
20     tmp = max(tmp, x.sum);
21     tmp = max(tmp, lson.smax);
22     tmp = max(tmp, rson.smax);
23 */
24     int tmp = max(lson.smax, rson.smax);
25     tmp = max(tmp, lson.rmax+rson.lmax);
26     x.smax = tmp;
27 }
28 void build(int x, int l, int r)
29 {
30     if (l == r){
31         t[x].sum = t[x].lmax = t[x].rmax = t[x].smax = a[l];
32         return;
33     }
34     int mid = l + r >> 1, lson = x<<1, rson = x<<1|1;
35     build(lson, l, mid);
36     build(rson, mid+1, r);
37     pushup(t[x], t[lson], t[rson]);
38 }
39 void update(int x, int l, int r, int p, int d)
40 {
41     if (l == r){
42         t[x].sum = t[x].lmax = t[x].rmax = t[x].smax = d;
43         return;
44     }
45     int mid = l + r >> 1;
46     if (p <= mid) update(x<<1, l, mid, p, d);
47     if (p > mid) update(x<<1|1, mid+1, r, p, d);
48     pushup(t[x], t[x<<1], t[x<<1|1]);
49 }
50 tree query(int s, int e, int x, int l, int r)
51 {
52     if (s <= l && r <= e){
53         return t[x];
54     }
55     int mid = l + r >> 1;
56     if (e <= mid) return query(s, e, x<<1, l, mid);
57     if (s > mid) return query(s, e, x<<1|1, mid+1, r);
58     tree p, q, ans;
59     p = query(s, mid, x<<1, l, mid);
60     q = query(mid+1, e, x<<1|1, mid+1, r);
61     pushup(ans, p, q);
62     return ans;
63 }
64 int main()
65 {
66     scanf("%d", &n);
67     for (int i = 1; i <= n; i++)
68         scanf("%d", &a[i]);
69     build(1, 1, n);
70     scanf("%d", &m);
71     int q, x, y;
72     for (int i = 0; i < m; i++){
73         scanf("%d %d %d", &q, &x, &y);
74         if (q == 1)
75             printf("%d\n", query(x, y, 1, 1, n).smax);
76         else
77             update(1, 1, n, x, y);
78     }
79     return 0;
80 }

SPOJ_2713 GSS4

SPOJ_2916 GSS5

分析:相比gss1,查询变成对左端点和右端点的不同区间限制,耐心地分类讨论就可以了。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 int n, m;
 5 int a[10100], sum[10100];
 6 struct tree{
 7     int sum, lmax, rmax, smax;
 8 } t[10100 << 2];
 9
10 int max(int a, int b)
11 {
12     return a>b?a:b;
13 }
14 void update(tree &x, tree lson, tree rson)
15 {
16     x.sum = lson.sum + rson.sum;
17     x.lmax = max(lson.lmax, lson.sum+rson.lmax);
18     x.rmax = max(rson.rmax, rson.sum+lson.rmax);
19     int tmp = max(lson.smax, rson.smax);
20     tmp = max(tmp, lson.rmax+rson.lmax);
21     x.smax = tmp;
22 }
23 void build(int x, int l, int r)
24 {
25     if (l == r){
26         t[x].sum = t[x].lmax = t[x].rmax = t[x].smax = a[l];
27         return;
28     }
29     int mid = l + r >> 1, lson = x<<1, rson = x<<1|1;
30     build(lson, l, mid);
31     build(rson, mid+1, r);
32     update(t[x], t[lson], t[rson]);
33 }
34 tree query(int s, int e, int x, int l, int r)
35 {
36     if (s <= l && r <= e){
37         return t[x];
38     }
39     int mid = l + r >> 1;
40     if (e <= mid) return query(s, e, x<<1, l, mid);
41     if (s > mid) return query(s, e, x<<1|1, mid+1, r);
42     tree p, q, ans;
43     p = query(s, mid, x<<1, l, mid);
44     q = query(mid+1, e, x<<1|1, mid+1, r);
45     update(ans, p, q);
46     return ans;
47 }
48 int main()
49 {
50     int T;
51     scanf("%d", &T);
52     while(T--)
53     {
54         scanf("%d", &n);
55         for (int i = 1; i <= n; i++)
56             scanf("%d", &a[i]);
57         sum[0] = 0;
58         for (int i = 1; i <= n; i++)
59             sum[i] = sum[i-1] + a[i];
60         build(1, 1, n);
61         scanf("%d", &m);
62         int x1, y1, x2, y2;
63         for (int i = 0; i < m; i++){
64             scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
65             int ans = 0;
66             if (y1 == x2){
67 //                ans = a[y1];
68 //                int tmp1 = 0, tmp2 = 0;
69 //                if (x1 <= y1-1) tmp1 = max(query(x1, y1-1, 1, 1, n).rmax, 0);
70 //                if (x2+1 <= y2) tmp2 = max(query(x2+1, y2, 1, 1, n).lmax, 0);
71 //                ans += tmp1 + tmp2;
72                 ans = query(x1, y1, 1, 1, n).rmax + query(x2, y2, 1, 1, n).lmax - a[y1];
73             }
74             else if (y1 < x2){
75                 ans = sum[x2-1] - sum[y1];
76                 ans += query(x1, y1, 1, 1, n).rmax + query(x2, y2, 1, 1, n).lmax;
77             }
78             else{
79                 int tmp = query(x2, y1, 1, 1, n).smax;
80                 ans = tmp;
81
82                 tmp = sum[y1-1] - sum[x2];
83                 tmp += query(x1, x2, 1, 1, n).rmax + query(y1, y2, 1, 1, n).lmax;
84                 ans = max(tmp, ans);
85
86                 tmp = query(x1, x2, 1, 1, n).rmax + query(x2, y1, 1, 1, n).lmax - a[x2];
87                 ans = max(tmp, ans);
88
89                 tmp = query(x2, y1, 1, 1, n).rmax + query(y1, y2, 1, 1, n).lmax - a[y1];
90                 ans = max(tmp, ans);
91
92             }
93             printf("%d\n", ans);
94         }
95     }
96     return 0;
97 }

SPOJ_4487 GSS6

SPOJ_6779 GSS7

SPOJ GSS系列 解题报告,布布扣,bubuko.com

时间: 2024-10-05 16:23:16

SPOJ GSS系列 解题报告的相关文章

SPOJ GSS系列解题报告

众所周知,\(GSS\)是用来练习线段树的一个非常好的系列. 依稀记得\(8\)月初还在\(qbxt\)时,某钟姓神仙说过 :"大家可以把\(GSS\)系列写一下,大概够大家写一个月了."虽然我很不想承认,但他确实说中了\(--\)虽然中间夹有做各种杂题和一些模拟赛\(--\) 题解 GSS 1 \(GSS\)系列最简单的一道题,也算是后面题目的一个基础. 给定一个序列,维护区间最大子段和. 我们维护这样几个东西\(:lsum, rsum, maxsum, maxval.\) 分别表示

SPOJ QTREE 系列解题报告

题目一 : SPOJ 375 Query On a Tree http://www.spoj.com/problems/QTREE/ 给一个树,求a,b路径上最大边权,或者修改a,b边权为t. 1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 7 using namespace s

SPOJ GSS系列 最大子段和 线段树+树链剖分+splay 1043 1557 1716 2713 2916 4487 6779

最大子段和的各种形式 题解内附每道题的 题意 题目链接 思路 SPOJ 1043 GSS1 静态区间求个最大子段和, 题解 SPOJ 1577 GSS2 和1一样,区别是若区间内存在相同的元素,则该元素只计算一次. 离线一下然后使劲跑.. 题解 SPOJ 1716 GSS3 和1一样,就是要支持单点修改 题解 SPOJ 2713 GSS4 ==普通线段树,感觉和这系列关系不大. 题解 SPOJ 2916 GSS5 题意有点怪,,跟3差不多,就是稍加强了点询问 题解 SPOJ 4487 GSS6

小Z 系列 解题报告

在你谷刷题时偶然发现有这么一个系列,大概\(15\)道题目左右. 而且蒟蒻发现,这个系列的出题人基本上全是LittleZ大佬OrzOrz. 于是心血来潮,想把这个系列全部写完,然后便有了本文. \(P.s.:\)按蒟蒻自己的做题顺序排列,不一定代表难易. \(1.\)小Z的矩阵 因为题目中给出的特征函数\(G(A)\)是对\(2\)取模后的结果,所以很容易就可以发现除对角线以外所有元素对答案的贡献均为\(0\),所以第一步单累计对角线贡献即可. 然后我们发现每翻转一行一列对答案无影响,即刚好翻转

Spring-2-H Array Diversity(SPOJ AMR11H)解题报告及测试数据

Array Diversity Time Limit:404MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Description Here we go! Let's define the diversity of a list of numbers to be the difference between the largest and smallest number in the list. For example, the d

Spring-2-J Goblin Wars(SPOJ AMR11J)解题报告及测试数据

Goblin Wars Time Limit:432MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Description The wizards and witches of Hogwarts School of Witchcraft found Prof. Binn's History of Magic lesson to be no less boring than you found your own history cla

Spring-2-A Magic Grid(SPOJ AMR11A)解题报告及测试数据

Magic Grid Time Limit:336MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Description Thanks a lot for helping Harry Potter in finding the Sorcerer's Stone of Immortality in October. Did we not tell you that it was just an online game ? uhhh!

Spring-2-B Save the Students(SPOJ AMR11B)解题报告及测试数据

Save the Students Time Limit:134MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Description Hogwarts is under attack by the Dark Lord, He-Who-Must-Not-Be-Named. To protect the students, Harry Potter must cast protective spells so that those w

排列组合(permutation)系列解题报告

本文讲解4道关于permutation的题目: 1. Permutation:输出permutation--基础递归 2. Permutation Sequence: 输出字典序排列的第k个permutation--推理3. Next Permutation:给定一个permutation中的序列,求字典序它的下一个permutation是什么--逻辑推理4. Permutation II:和第一题有细微的差别: 对于一个可能有重复元素的数组输出所有permutation--有条件dfs