一开始看不懂题解,看懂了题解之后觉得还是挺妙的。

好多题解里都提到了HH的项链,但是我觉得关系并不大啊……

先把所有询问离线下来按照右端点排序,按照询问的要求一个一个加入数字,怎么加入数字,我们设计一颗特别的线段树:

假设当前我们在$[1, r]$中已经加完了数字,那么线段树的叶子结点$l$表示$\sum_{i = l}^{r}a_i$,非叶子结点在左右儿子之间取个最大值就好了,然后我们发现这样子答案就是询问区间中曾经出现过的数的最大的一个值,我们只要把这个最大值顺便保留计算一下就好了。

考虑一下怎么添加数,对于一个下标$i$,只要在$[pre_i + 1, i]$中区间加$a_i$即可($pre_i$表示前一个$a_i$出现的位置)。

用两个标记维护当前最大值和历史最大值,实现起来有一些细节。

时间复杂度$O(nlogn)$。

Code:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll; const int N = 1e5 + ;
const int Fix = 1e5; int n, qn, a[N], head[N << ], pre[N]; struct Querys {
int l, r, id;
ll res; friend bool operator < (const Querys &x, const Querys &y) {
return x.r < y.r;
} } q[N]; inline void read(int &X) {
X = ; char ch = ; int op = ;
for(; ch > '' || ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} inline ll max(ll x, ll y) {
return x > y ? x : y;
} template <typename T>
inline void chkMax(T &x, T y) {
if(y > x) x = y;
} namespace SegT {
struct Node {
ll mx, tag, his, htag; inline Node (ll nowMx = 0LL, ll nowTag = 0LL, ll nowHis = 0LL, ll nowHtag = 0LL) {
mx = nowMx, tag = nowTag, his = nowHis, htag = nowHtag;
} } s[N << ]; #define lc p << 1
#define rc p << 1 | 1
#define mid ((l + r) >> 1)
#define mx(p) s[p].mx
#define tag(p) s[p].tag
#define his(p) s[p].his
#define htag(p) s[p].htag inline void up(int p) {
mx(p) = max(mx(lc), mx(rc));
his(p) = max(his(lc), his(rc));
} inline void down(int p) {
chkMax(his(lc), mx(lc) + htag(p));
chkMax(his(rc), mx(rc) + htag(p));
mx(lc) += tag(p), mx(rc) += tag(p);
chkMax(htag(lc), tag(lc) + htag(p));
chkMax(htag(rc), tag(rc) + htag(p));
tag(lc) += tag(p), tag(rc) += tag(p);
tag(p) = htag(p) = ;
} void modify(int p, int l, int r, int x, int y, ll v) {
if(x <= l && y >= r) {
mx(p) += v;
chkMax(his(p), mx(p));
tag(p) += v;
chkMax(htag(p), tag(p));
return;
} down(p);
if(x <= mid) modify(lc, l, mid, x, y, v);
if(y > mid) modify(rc, mid + , r, x, y, v);
up(p);
} ll query(int p, int l, int r, int x, int y) {
if(x <= l && y >= r) return s[p].his;
down(p); ll res = ;
if(x <= mid) chkMax(res, query(lc, l, mid, x, y));
if(y > mid) chkMax(res, query(rc, mid + , r, x, y));
return res;
} } using namespace SegT; int main() {
read(n);
for(int i = ; i <= n; i++) {
read(a[i]);
pre[i] = head[a[i] + Fix];
head[a[i] + Fix] = i;
} read(qn);
for(int i = ; i <= qn; i++) {
read(q[i].l), read(q[i].r);
q[i].id = i, q[i].res = 0LL;
} sort(q + , q + + qn);
for(int j = , i = ; i <= qn; i++) {
for(; j <= q[i].r && j <= n; j++)
modify(, , n, pre[j] + , j, 1LL * a[j]);
ll now = query(, , n, q[i].l, q[i].r);
q[q[i].id].res = now;
} for(int i = ; i <= qn; i++)
printf("%lld\n", q[i].res); return ;
}

SP1557 GSS2 - Can you answer these queries II的更多相关文章

  1. SP1557 GSS2 - Can you answer these queries II(线段树)

    传送门 线段树好题 因为题目中相同的只算一次,我们可以联想到HH的项链,于是考虑离线的做法 先把所有的询问按$r$排序,然后每一次不断将$a[r]$加入线段树 线段树上维护四个值,$sum,hix,s ...

  2. SPOJ GSS2 - Can you answer these queries II(线段树 区间修改+区间查询)(后缀和)

    GSS2 - Can you answer these queries II #tree Being a completist and a simplist, kid Yang Zhe cannot ...

  3. bzoj 2482: [Spoj GSS2] Can you answer these queries II 线段树

    2482: [Spoj1557] Can you answer these queries II Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 145 ...

  4. spoj gss2 : Can you answer these queries II 离线&&线段树

    1557. Can you answer these queries II Problem code: GSS2 Being a completist and a simplist, kid Yang ...

  5. SPOJ GSS2 Can you answer these queries II

    Time Limit: 1000MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Description Being a ...

  6. SPOJ 1557 GSS2 - Can you answer these queries II (线段树+维护历史最值)

    都说这题是 GSS 系列中最难的,今天做了一下,名副其实 首先你可以想到各种各样的在线乱搞想法,线段树,主席树,平衡树,等等,但发现都不太可行. 注意到题目也没有说强制在线,因此可以想到离线地去解决这 ...

  7. SPOJ1557 GSS2 Can you answer these queries II 历史最值线段树

    传送门 题意:给出一个长度为$N$的数列,$Q$次询问,每一次询问$[l,r]$之间的最大子段和,相同的数只计算一次.所有数字的绝对值$\leq 10^5$ GSS系列中不板子的大火题,单独拿出来写 ...

  8. SPOJ GSS2 Can you answer these queries II ——线段树

    [题目分析] 线段树,好强! 首先从左往右依次扫描,线段树维护一下f[].f[i]表示从i到当前位置的和的值. 然后询问按照右端点排序,扫到一个位置,就相当于查询区间历史最值. 关于历史最值问题: 标 ...

  9. BZOJ2482: [Spoj1557] Can you answer these queries II

    题解: 从没见过这么XXX的线段树啊... T_T 我们考虑离线做,按1-n一个一个插入,并且维护区间[ j,i](i为当前插入的数)j<i的最优值. 但这个最优值!!! 我们要保存历史的最优值 ...

随机推荐

  1. jQuery使用prop设置checkbox全选、反选

    $(function(){     var checkbox = $("input[type='checkbox']");     //全选     $('#select-all' ...

  2. k8s api server ha 连接配置问题

    常见的lb 负载有硬件的f5 big-ip  ,同时对于互联网公司大家常用的是nginx  haproxy 了解k8s 集群高可用的都知道 api server  是无状态的(etcd 解决了),但是 ...

  3. 浪潮各机型管理芯片BMC IP(智能平台管理接口)设置

    NF5240m3/NF5140m3/NF5280m3/SA5212H2/NP5540M3NF5270M3/NF5170M3/NF8420m3 IPMI主板集成管理芯片BMC IP 设置开机按DEL键进 ...

  4. vue的双向绑定原理解析(vue项目重构二)

    现在的前端框架 如果没有个数据的双向/单向绑定,都不好意思说是一个新的框架,至于为什么需要这个功能,从jq或者原生js开始做项目的前端工作者,应该是深有体会. 以下也是个人对vue的双向绑定原理的一些 ...

  5. selenium - css 定位

    前言: CSS(Cascading Style Sheets)是一种语言,它被用来描述 HTML 和 XML 文档的表现. CSS 使用选择器来为页面元素绑定属性.这些选择器可以被 selenium ...

  6. java代码练习======每隔5行打印数字

    总结:当我们感觉数字排列横排,竖排不好看的时候,学会空几行在排列,哎呦,效果不错喔 package com.aa; public class West2 { public static void ma ...

  7. java中输入3个数,从大到小的输出。。。。

    总结:我暂时不能理解,C语言时讲过,java里就不理解了 package com.a; import java.sql.Date; import java.util.Scanner; //输入三个数, ...

  8. Zabbix自定义监控网站服务是否能够正常响应

     监测tcp连接数文件名: /etc/zabbix/zabbix_agentd.conf.d/count_tcp.conf UserParameter=count.tcp,netstat -s|g ...

  9. vue-cli脚手架build目录下utils.js工具配置文件详解

    此文章用来解释vue-cli脚手架build目录中的utils.js配置文件 此配置文件是vue开发环境的wepack相关配置文件,主要用来处理css-loader和vue-style-loader ...

  10. JAVA,模拟HTTP登录(略有修改) ----转载自http://zhoujingxian.iteye.com/blog/439738

    /* * 网上的一个模拟登录或者模拟注册程序 * 2013-8-5 */ package Socket_Http; import java.io.BufferedReader; import java ...