SP1557 GSS2 - Can you answer these queries II
一开始看不懂题解,看懂了题解之后觉得还是挺妙的。
好多题解里都提到了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的更多相关文章
- SP1557 GSS2 - Can you answer these queries II(线段树)
		
传送门 线段树好题 因为题目中相同的只算一次,我们可以联想到HH的项链,于是考虑离线的做法 先把所有的询问按$r$排序,然后每一次不断将$a[r]$加入线段树 线段树上维护四个值,$sum,hix,s ...
 - 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 ...
 - 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 ...
 - 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 ...
 - SPOJ GSS2 Can you answer these queries II
		
Time Limit: 1000MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Description Being a ...
 - SPOJ 1557 GSS2 - Can you answer these queries II (线段树+维护历史最值)
		
都说这题是 GSS 系列中最难的,今天做了一下,名副其实 首先你可以想到各种各样的在线乱搞想法,线段树,主席树,平衡树,等等,但发现都不太可行. 注意到题目也没有说强制在线,因此可以想到离线地去解决这 ...
 - SPOJ1557 GSS2 Can you answer these queries II 历史最值线段树
		
传送门 题意:给出一个长度为$N$的数列,$Q$次询问,每一次询问$[l,r]$之间的最大子段和,相同的数只计算一次.所有数字的绝对值$\leq 10^5$ GSS系列中不板子的大火题,单独拿出来写 ...
 - SPOJ GSS2 Can you answer these queries II ——线段树
		
[题目分析] 线段树,好强! 首先从左往右依次扫描,线段树维护一下f[].f[i]表示从i到当前位置的和的值. 然后询问按照右端点排序,扫到一个位置,就相当于查询区间历史最值. 关于历史最值问题: 标 ...
 - BZOJ2482: [Spoj1557] Can you answer these queries II
		
题解: 从没见过这么XXX的线段树啊... T_T 我们考虑离线做,按1-n一个一个插入,并且维护区间[ j,i](i为当前插入的数)j<i的最优值. 但这个最优值!!! 我们要保存历史的最优值 ...
 
随机推荐
- NSArray四种遍历方法
 - haproxy中两个常用的宏
			
list_for_each(pos, head) pos.head 都为list类型 一般来说,head是list的虚拟头,依次取list上的各个节点 container_of(ptr, type, ...
 - subline自定义快捷键
			
由于感觉原始subline的运行快捷键ctrl+b不是很方便,尝试修改,方法如下: 打开首选项 --> 快捷键设置 Key Bindings -Default //这个表示系统默认的快捷键.Ke ...
 - 杂项-公司:Netflix百科-un
			
ylbtech-杂项-公司:Netflix百科-un Netflix(Nasdaq NFLX) 成立于1997年,是一家在线影片租赁提供商,主要提供Netflix超大数量的DVD并免费递送,总部位于美 ...
 - Java-Maven-Runoob:Maven 自动化部署
			
ylbtech-Java-Maven-Runoob:Maven 自动化部署 1.返回顶部 1. Maven 自动化部署 项目开发过程中,部署的过程包含需如下步骤: 将所的项目代码提交到 SVN 或者代 ...
 - PHP面向对象深入研究之【组合模式与装饰模式】
			
组合模式 定义:组合模式定义了一个单根继承体系,使具有截然不同职责的集合可以并肩工作. 一个军队的案例, <?php abstract class Unit { // 个体 abstract f ...
 - JAVA基础知识——IO
			
首先看一下JAVA IO的类继承关系
 - LT3756/LT3756-1/LT3756-2 - 100VIN、100VOUT LED 控制器
			
LT3756/LT3756-1/LT3756-2 - 100VIN.100VOUT LED 控制器 特点 3000:1 True Color PWMTM调光 宽输入电压范围:6V至 100V 输出电压 ...
 - gcc及其选项详解
			
1.简介: gcc是gnu旗舰产品,目前基本上就是和unix捆绑在一起分发的.这个东西功能强大,但是有多达上千个选项,其用户手册也有将近一万行.虽然其中的多数选项平时很少用到.但是不管装软件还是写程序 ...
 - 多路复用IO
			
多路复用IO(IO multiplexing) IO multiplexing这个词可能有点陌生,但是如果我说select/epoll,大概就都能明白了.有些地方也称这种IO方式为事件驱动IO (ev ...