orz PoPoQQQ 的神题。

我的想法是:给每一个高度都维护一个 $01$ 序列,大概就是维护一个 $Map[i][j]$ 的矩阵,然后 $Map[i][j]$ 表示第 $i$ 根柱子的高度是否 $\ge j$。

那么怎么维护 $Map[i][j]$ 呢。。?

首先我们把柱子按照高度从小到大排序,然后依次给每个高度建主席树,初始时 $Map[i][0]$ 全是 $1$,然后如果当前高度 $i$ 比某个柱子 $j$ 的高度要大了,那么就单点修改 $Map[i][j]$,然后这个就是主席树动态开节点的经典操作嘛。然后我们就相当于是要维护每一个高度的主席树,并记录其最长连续子段,记高度 $i$ 的主席树的最长连续子段长 $len_i$,那么最大子矩阵就是:

$$max\{i\times len_i | i = 1 - Max\_height\}$$

然后每次单点修改只会改变一个主席树的最长连续子段,所以我们可以再弄一个堆维护这个答案。

时间空间复杂度均为 $O((n+m)\log h + h)$,可以过掉本题。

其实 $h$ 可以扩大到 $10^9$,这样的话我们就需要离散化一下,反正有用的高度只有 $O(n + m)$ 种。

 #include <queue>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
#define N 100000 + 5
#define M 1000000 + 5
#define SIZE 10000000 + 5 int n, m, Max, tot, A[N], Ord[N], Root[M]; struct Segment_Tree
{
int l, r, Lcombo, Rcombo, combo;
}h[SIZE]; struct Node
{
int id;
LL square;
Node (int _id = , LL _square = ) {id = _id, square = _square;}
bool operator < (const Node a) const
{
return square < a.square || (square == a.square && id < a.id);
}
}; priority_queue <Node> Q; inline LL getint()
{
char ch = '\n';
for (; ch != '-' && (ch > '' || ch < ''); ch = getchar()) ;
int f = ch == '-' ? - : ;
LL res = ch == '-' ? : ch - '';
for (ch = getchar(); ch >= '' && ch <= ''; ch = getchar())
res = (res << ) + (res << ) + ch - '';
return res * f;
} inline bool cmp(int u, int v)
{
return A[u] < A[v];
} inline void Build(int &x, int l, int r)
{
x = ++ tot;
h[x].Lcombo = h[x].Rcombo = h[x].combo = r - l + ;
if (l == r) return ;
int mid = l + r >> ;
Build(h[x].l, l, mid);
Build(h[x].r, mid + , r);
} inline void update(int x, int l, int r)
{
int mid = l + r >> ;
if (h[h[x].l].Lcombo == mid - l + )
h[x].Lcombo = h[h[x].l].Lcombo + h[h[x].r].Lcombo;
else h[x].Lcombo = h[h[x].l].Lcombo;
if (h[h[x].r].Rcombo == r - mid)
h[x].Rcombo = h[h[x].r].Rcombo + h[h[x].l].Rcombo;
else h[x].Rcombo = h[h[x].r].Rcombo;
h[x].combo = max(max(h[h[x].l].combo, h[h[x].r].combo), h[h[x].l].Rcombo + h[h[x].r].Lcombo);
} inline void Modify(int &x, int l, int r, int t)
{
h[++ tot] = h[x];
x = tot;
if (l == r)
{
h[x].Lcombo = h[x].Rcombo = h[x].combo = ;
return ;
}
int mid = l + r >> ;
if (t <= mid) Modify(h[x].l, l, mid, t);
else Modify(h[x].r, mid + , r, t);
update(x, l, r);
} int main()
{
n = getint(), m = getint();
for (int i = ; i <= n; Ord[i] = i, i ++)
{
A[i] = getint();
Max = max(Max, A[i]);
}
sort(Ord + , Ord + n + , cmp);
Build(Root[], , n);
for (int i = , t = ; i <= Max; i ++)
{
Root[i] = Root[i - ];
for (; A[Ord[t]] == i - && t <= n; t ++)
Modify(Root[i], , n, Ord[t]);
Q.push(Node(i, (LL) h[Root[i]].combo * i));
}
Node x = Q.top();
LL last = x.square;
printf("%lld\n", last);
while (m --)
{
int pos = (int) (getint() ^ last);
Modify(Root[A[pos]], , n, pos);
Q.push(Node(A[pos], (LL) h[Root[A[pos]]].combo * A[pos]));
A[pos] --;
Node x;
for (x = Q.top(); (LL) x.id * h[Root[x.id]].combo != x.square; Q.pop(), x = Q.top()) ;
last = x.square;
printf("%lld\n", last);
} return ;
}

Rectangle_Gromah

【弱省胡策】Round #7 Rectangle 解题报告的更多相关文章

  1. 【弱省胡策】Round #5 Count

    [弱省胡策]Round #5 Count 太神仙了. \(DP\)做法 设\(f_{n,m,d,k}\)表示\(n*m\)的矩阵,填入第\(k\)个颜色,并且第\(k\)个颜色最少的一列上有\(d\) ...

  2. 弱省胡策 Magic

    弱省胡策 Magic 求\(n\)个点\(n\)的条边的简单联通图的个数. 毒瘤,还要写高精. 我们枚举环的大小\(k\),\(\displaystyle ans=\sum_{k=3}^nC_n^k ...

  3. luoguP3769 [CH弱省胡策R2]TATT

    luoguP3769 [CH弱省胡策R2]TATT PS:做这题前先切掉 P4148简单题,对于本人这样的juruo更助于理解,当然dalao就当练练手吧 题目大意: 现在有n个四维空间中的点,请求出 ...

  4. Codeforces Round 665 赛后解题报告(暂A-D)

    Codeforces Round 665 赛后解题报告 A. Distance and Axis 我们设 \(B\) 点 坐标为 \(x(x\leq n)\).由题意我们知道 \[\mid(n-x)- ...

  5. Codeforces Round 662 赛后解题报告(A-E2)

    Codeforces Round 662 赛后解题报告 梦幻开局到1400+的悲惨故事 A. Rainbow Dash, Fluttershy and Chess Coloring 这个题很简单,我们 ...

  6. Codeforces Educational Round 92 赛后解题报告(A-G)

    Codeforces Educational Round 92 赛后解题报告 惨 huayucaiji 惨 A. LCM Problem 赛前:A题嘛,总归简单的咯 赛后:A题这种**题居然想了20m ...

  7. 【ContestHunter】【弱省胡策】【Round0】(A)&【Round1】(B)

    DP+容斥原理or补集转化?/KD-Tree 唔……突然发现最早打的两场(打的最烂的两场)没有写记录……(太烂所以不忍记录了吗... 还是把搞出来了的两道题记录一下吧= =勉强算弥补一下缺憾…… Ro ...

  8. Codeforces Round #277.5 解题报告

    又熬夜刷了cf,今天比正常多一题.比赛还没完但我知道F过不了了,一个半小时贡献给F还是没过--应该也没人Hack.写写解题报告吧= =. 解题报告例如以下: A题:选择排序直接搞,由于不要求最优交换次 ...

  9. 【弱省胡策】Round #5 Construct 解题报告

    这个题是传说中的 Hack 狂魔 qmqmqm 出的构造题.当然要神. 这个题的本质实际上就是构造一个图,然后使得任意两点间都有长度为 $k$ 的路径相连,然后对于任意的 $i < k$,都存在 ...

随机推荐

  1. java基础学习总结三(jdk7新特性、变量(局部变量和成员变量)、常量以及运算符)

    一:jdk7新特性 可以表示二进制数值,以0b开头,中间可以使用下划线_分隔符.如下: @Test /** * 测试jdk新特性 */ public void testJdk7(){ int a=0b ...

  2. [ImportNew]Java中的并发处理

    本文来源:http://www.importnew.com/14506.html 这篇文章讨论了Java应用中并行处理的多种方法.从自己管理Java线程,到各种更好几的解决方法,Executor服务. ...

  3. JS HTML标签尺寸距离位置定位计算

    四种浏览器对 clientHeight.offsetHeight.scrollHeight.clientWidth.offsetWidth 和 scrollWidth 的解释差异 网页可见区域宽:do ...

  4. 面试相关的技术问题--WEB基础

    1. servlet生命周期.各个方法 和工作原理servlet的生命周期包括三个阶段,分别是:初始化阶段:调用init()方法(整个生命周期内只被调用一次)响应客户端请求阶段:service()终止 ...

  5. Linux下如何查看哪些端口处于监听状态

    查看某一端口的占用情况: lsof -i:端口号 前提:首先你必须知道,端口不是独立存在的,它是依附于进程的.某个进程开启,那么它对应的端口就开启了,进程关闭,则该端口也就关闭了.下次若某个进程再次开 ...

  6. [转] sql数据类型 varchar与nvarchar的区别

    SQL Server提供两种数据类型来存储字符信息.在如何在SQL Server或应用程序中使用方面,这两种数据类型大致是一样的.差别在于nvarchar是用于存储处理数据库图表中多语言数据的Unic ...

  7. C# is 强制转换

    在平时开发中,经常遇上强制转换,在这过程中经常遇上null对象转换为值类型,如果不判断的情况下在编译的时候不会出错,但程序一运行就抛出错误.好在C#为我们提供了is ,它判断一个对象如果成立就转换,如 ...

  8. partial与sorted

    import functools sorted_ignore_case = functools.partial(sorted,cmp=lambda s1, s2: cmp(s1.upper(), s2 ...

  9. mina2.0 spring

    Apache MINA是一个网络应用程序框架,它可以帮助用户开发的高性能.高扩展性的网络应用程序.它提供了一个抽象的事件驱动的异步API在不同传输如TCP/IP和UDP/IP通过java NIO. A ...

  10. 376. Wiggle Subsequence

    A sequence of numbers is called a wiggle sequence if the differences between successive numbers stri ...