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. [转]Oracle 调用存储过程并显示结果集 Oracle.DataAccess.Client OracleDbType.RefCursor

    本文转自:http://liye9801.blog.163.com/blog/static/6019703200901244448950/ 今天学习了一个Oracle中的存储过程,一开始便被如果返回结 ...

  2. Linux下root密码忘记的解决办法

    {启动方式} ========================================================================== 一. lilo 1. 在出现 lil ...

  3. 从lambda到函数式编程

    Object.send(:remove_const,'TRUE') Object.send(:remove_const,'FALSE') def to_integer(pro) pro[-> n ...

  4. linux commond

    1  vi /etc/sysconfig/network-scripts/ifcfg-eth0     2  ifconfig    3  ping 172.22.14.59    4  ping 1 ...

  5. modelsim 仿真时出现无限迭代(iteration reach limitation)的原因及其解决办法

    modelsim 仿真时出现无限迭代(iteration reach limitation) 出现这种故障的原因:  一般都是代码里出现的组合逻辑无限循环或者组合逻辑A产生signal_A,signa ...

  6. 【C语言】03-printf和scanf函数

    一.printf函数 这是在stdio.h中声明的一个函数,因此使用前必须加入#include <stdio.h>,使用它可以向标准输出设备(比如屏幕)输出数据 1.用法 1> pr ...

  7. HTML5 服务器发送事件

    单向传输:服务器端——>客户端   作用:传回的能每过3s重新刷新一遍.从而能过跟数据库同步,与ajax配合使用   一.客户端写法 必须的用 message 方法   JSON.parse() ...

  8. 在Activiti官方源码上提交的两个bugfix

    前段时间在Activiti官方源码上提交了两个bugfix,截图为证. 第1个是BPMN model输出的bug:

  9. ASP连接MYSQL数据库

    <% strconnection="driver={mysql odbc 3.51 driver};database=weste_net;server=localhost;uid=ro ...

  10. 一个ASP函数库

    <% '****************************** '类名: '名称:通用库 '日期:2008/10/28 '作者:by xilou '网址: '描述:通用库 '版权:转载请注 ...