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. postgresql crosstab 行转列函数

    http://blog.csdn.net/hexin373/article/details/19242833

  2. 收回动态VHD的未使用空间

    随着虚拟机的运行,虚拟机磁盘所占空间越来越大,而实际使用并没有那么大,考虑回收未使用部分. 收回动态VHD的未使用空间(压缩VHD) 有一种方法是ghost,两个vhd文件对拷.本文不是那个方法 本文 ...

  3. 【转】Error: no `server' JVM at `C:\Program Files\Java\jre6\bin\server\jvm.dll'.解决办法

    出现问题: 用java -jar XXX.jar -server -Xms900m -Xmx900m 或者 java -server -version 提示错误 Error: no `server' ...

  4. 05顺序队列_Queue--(栈与队列)

    #include "stdio.h" #include "stdlib.h" #include "io.h" #include " ...

  5. [译]JavaScript 错误和处理

    JavaScript的调试是一个噩梦:一些错误刚开始很难理解,并且给出的错误函数也经常是没用的.如果把错误都列出来并给出解决办法会不会很有用呢. 下面列出了JavaScript一系列的奇怪错误.对于同 ...

  6. 2016.7.2this的应用

    this有三个应用: 1.就是在类的方法中参数与成员参数重名了,那么用this.参数名=参数名来区分它们: 2.当一个引用对象要调用另一个已经有具体实例的引用对象,那么通过在类的定义中后面加publi ...

  7. bzoj1016:[JSOI2008]最小生成树计数

    思路:模拟kruskal的过程,可以发现对于所有权值相同的边,有很多种选择的方案,而且权值不同的边并不会相互影响,因为先考虑权值较小的边,权值比当前权值大的边显然不在考虑范围之内,而权值比当前权值小的 ...

  8. 九度OJ 1351 数组中只出现一次的数字

    题目地址:http://ac.jobdu.com/problem.php?pid=1351 题目描述: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 输 ...

  9. 九度OJ 1513 二进制中1的个数

    题目地址:http://ac.jobdu.com/problem.php?pid=1513 题目描述: 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 输入: 输入可能包含多个测试样 ...

  10. Yii 通过widget小物件生成添加表单

    通过widget小物件创建添加商品的表单 视图里,表单以endWidget();?>结束 最终效果: 把表单提交过来的信息保存到数据库中去. 补充要点: 密码表单: <?php echo ...