SPOJ : Can you answer these queries合集
Can you answer these queries I
题意:给定一个序列。支持询问区间最大子段和。 \(n,q\le 50000,|a_i|\le 10000\)
线段树直接维护即可
Can you answer these queries II
题意:给定一个序列。支持询问区间最大子段和,重复数字只算一次。 \(n,q\le 100000,|a_i|\le 10^9\)
看似和上一题相同,实际难度提高不少........
离线,按 \(r\) 排序,扫描线当前扫到 \(i\) 的时候,对每一个叶节点维护它的到 \(i\) 的去重的元素和,还有该值其历史最大值,区间就从叶节点那里继承信息
记 \(pre_i\) 表示上一个值为 \(a_i\) 的数字在什么地方,那么就是区间加 \(a_i\),可以打懒标记来完成这个操作
对于历史最大值的标记,观察到它是一段一段区间,直接维护就好了
Can you answer these queries III
题意:给定一个序列。支持询问区间最大子段和和单点修改。 \(n,q\le 100000,|a_i|\le 10^9\)
线段树直接维护即可,也可以使用动态 \(dp\) ,构造矩阵如下:
\[ \left\{ \begin{matrix} a_i & -\infty & a_i \\ a_i & 0 & a_i\\ -\infty & -\infty & 0 \end{matrix} \right\} \]
维护区间乘积即可
Can you answer these queries IV
题意:给定一个序列。支持区间开根,询问区间和。 \(n,q\le 10^5,a_i\le 10^{18}\)
考虑每个数字被开根很少次之后就会变成 \(1\) ,于是维护区间 \(1\) 的个数,如果有不是 \(1\) 的暴力修改即可
Can you answer these queries V
题意:给定一个序列。查询左端点在 \([x_1,y_1]\) 之间,且右端点在 \([x_2,y_2]\) 之间的最大子段和,数据保证 \(x_1\leq x_2,y_1\leq y_2\) ,但是不保证端点所在的区间不重合。 \(n,q\le 10000,|a_i|\le 10000\)
设 \(q(l,r)\) 表示 \([l,r]\) 区间最大子段和,\(ql(l,r)\) 表示以 \(l\) 为左端点且右端点不超过 \(r\) 的最大子段和,\(qr(l,r)\) 相反
以上三个操作很容易使用线段树做到。
分两种情况讨论:
如果 \([x_1,y_1]\) 与 \([x_2,y_2]\) 没有交:答案为 \(sum(y_1,x_2)+qr(x_1,y_1)+ql(x_2,y_2)\)
如果有交,分三种情况讨论
- 左右端点都在 \([x_2,y_1]\) 中,答案就是 \(q(x_2,y_1)\)
- 左右端点都不在 \([x_2,y_1]\) 中,答案为 \(sum(x_2,y_1)+qr(x_1,x_2)+ql(y_1,y_2)\)
- 一个在而一个不在,答案为 \(max(qr(x_1,x_2)+ql(x_2,y_1),qr(x_2,y_1)+ql(y_1,y_2))\)
都讨论出来取个 \(max\) 即可
Can you answer these queries VI
题意:给定一个序列,支持单点插入,单点删除,单点修改,求区间最大子段和。 \(n,q\le 10^5\)
就是把线段树改成平衡树,除了难写一些以外没什么意义。
Can you answer these queries VII
题意:给定一棵树,支持求链最大子段和,链赋值。 \(n,q\le 10^5\)
LCT 直接上即可
Can you answer these queries VIII
题意:给定一个序列,支持单点插入,单点删除,单点修改,求 \(\sum_{i=l}^ra[i]\times (i-l+1)^k\) \(n,q\le 10^5,k\le 10\)
注意到 \(k\) 很小,直接二项式定理展开,用平衡树维护序列可以做到 \(O(nk^2+mk^2logn)\)