【Foreign】画方框 [主席树]
画方框
Time Limit: 10 Sec Memory Limit: 256 MB
Description

Input

Output
输出一行一个整数,表示 CD 最多可能画了几个方框。
Sample Input
3
1 1 1
1 0 1
1 1 1
Sample Output
9
HINT

Main idea
给定一个01矩阵,1表示有标记,询问正方形方框的个数。
Solution
首先,我们先从 维护对角线上的点 这一层面来考虑。
我们先把一个点 能向左向上拓展的最大长度 以及 能向右向下的最长长度 预处理出来。
那么这时候,我们考虑 对于一条对角线上的点 怎么 在O(nlogn)以内 统计出答案。必然要用到某些数据结构。
举个例子,比如这个数据:
1 1 1 1
1 0 0 0
1 0 0 1
1 0 1 1
我们现在统计中间对角线的答案。
现在查询第一个点(1,1),他向右向下拓展长度为 4 。
就是查询,后面三个点中 可以向左上拓展的长度 (2,2)>=1 (3,3)>=2 (4,4)>=3,
这三个条件满足了几个。
这样的话,我们发现:每次统计一个点的时候 查询的就是:在这个点 可以向右向下拓展 到的范围内,它后面的第 i 个点 可以向左向上拓展长度 是否 > i。
我们发现:查询后面若干个数的值是否 > 一个等差数列比较复杂。
于是乎,若统计第id个的答案,后面第num个点(在向右向下范围内)可以被统计所需要满足的条件是:num - id + 1 <= val 也就是 num - val + 1 <= id。(其中val表示 这个点可以向左向上拓展的长度)
所以我们如果把 i - val + 1 加入到一个数据结构中的话,
查询的就是:某一范围内 <=一个定值 的数的个数。
那直接用主席树来做就好了。
这样我们就解决了这个问题 QWQ。
Code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<queue>
using namespace std;
typedef long long s64; const int ONE = ;
const int INF = ; int n;
int a[ONE][ONE];
int Ans; struct power
{
int left, right;
int up, down;
int L, R;
}A[ONE][ONE]; int cnt, res;
struct point
{
int root;
int value;
int left, right;
}Node[ONE * ]; int get()
{
int res=,Q=;char c;
while( (c=getchar())< || c> )
if(c=='-')Q=-;
res=c-;
while( (c=getchar())>= && c<= )
res=res*+c-;
return res*Q;
} void Deal_first()
{
for(int i = ; i <= n; i++)
{
for(int j = n; j >= ; j--)
if(a[i][j]) A[i][j].right = A[i][j + ].right + ;
else A[i][j].right = ;
for(int j = ; j <= n; j++)
if(a[i][j]) A[i][j].left = A[i][j - ].left + ;
else A[i][j].left = ;
} for(int j = ; j <= n; j++)
{
for(int i = n; i >= ; i--)
if(a[i][j]) A[i][j].down = A[i + ][j].down + ;
else A[i][j].down = ;
for(int i = ; i <= n; i++)
if(a[i][j]) A[i][j].up = A[i - ][j].up + ;
else A[i][j].up = ;
} for(int i = ; i <= n; i++)
for(int j = ; j <= n; j++)
A[i][j].L = min(A[i][j].left, A[i][j].up),
A[i][j].R = min(A[i][j].right, A[i][j].down);
} void Update(int &x, int y, int L, int R, int Q, int val)
{
x = ++cnt;
Node[x].left = Node[y].left;
Node[x].right = Node[y].right;
Node[x].value = Node[y].value + val;
if(L == R) return; int M = L + R >> ;
if(Q <= M)
Update(Node[x].left, Node[y].left, L, M, Q, val);
else
Update(Node[x].right, Node[y].right, M + , R, Q, val);
} void Query(int x, int y, int l, int r, int L, int R)
{
if(L <= l && r <= R)
{
res += Node[y].value - Node[x].value;
return;
} int mid = l + r >> ; if(L <= mid) Query(Node[x].left, Node[y].left, l, mid, L, R);
if(mid + <=R) Query(Node[x].right, Node[y].right, mid + , r, L, R);
} int main()
{
n = get();
for(int i = ; i <= n; i++)
for(int j = ; j <= n; j++)
a[i][j] = get(); Deal_first(); for(int id = ; id <= n; id++)
{
for(int x = id, y = ; x <= n; x++, y++)
Update(Node[y].root, Node[y - ].root, , INF, y - A[x][y].L + , ); for(int x = id, y = ; x <= n; x++, y++)
{
res = ;
if(A[x][y].R)
Query(Node[y - ].root, Node[y + A[x][y].R - ].root, , INF, , y);
Ans += res;
} cnt = ;
for(int i = ; i <= cnt; i++)
Node[i].left = Node[i].right = Node[i].root = Node[i].value = ;
} for(int id = ; id <= n; id++)
{
for(int y = id, x = ; y <= n; y++, x++)
Update(Node[x].root, Node[x - ].root, , INF, x - A[x][y].L + , ); for(int y = id, x = ; y <= n; y++, x++)
{
res = ;
if(A[x][y].R)
Query(Node[x - ].root, Node[x + A[x][y].R - ].root, , INF, , x);
Ans += res;
} cnt = ;
for(int i = ; i <= cnt; i++)
Node[i].left = Node[i].right = Node[i].root = Node[i].value = ;
} printf("%d", Ans);
}
【Foreign】画方框 [主席树]的更多相关文章
- 主席树入门(区间第k大)
主席树入门 时隔5个月,我又来填主席树的坑了,现在才发现学算法真的要懂了之后,再自己调试,慢慢写出来,如果不懂,就只会按照代码敲,是不会有任何提升的,都不如不照着敲. 所以搞算法一定要弄清原理,和代码 ...
- 【BZOJ】1146: [CTSC2008]网络管理Network(树链剖分+线段树套平衡树+二分 / dfs序+树状数组+主席树)
http://www.lydsy.com/JudgeOnline/problem.php?id=1146 第一种做法(时间太感人): 第二种做法(rank5,好开心) ================ ...
- BZOJ 4539: [Hnoi2016]树 [主席树 lca]
4539: [Hnoi2016]树 题意:不想写.复制模板树的子树,查询两点间距离. *** 终于有一道会做的题了...... 画一画发现可以把每次复制的子树看成一个大点来建一棵树,两点的lca一定在 ...
- bzoj 4448 [Scoi2015]情报传递 (树链剖分+主席树)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4448 题面: Description 奈特公司是一个巨大的情报公司,它有着庞大的情报网络 ...
- 线段树简单入门 (含普通线段树, zkw线段树, 主席树)
线段树简单入门 递归版线段树 线段树的定义 线段树, 顾名思义, 就是每个节点表示一个区间. 线段树通常维护一些区间的值, 例如区间和. 比如, 上图 \([2, 5]\) 区间的和, 为以下区间的和 ...
- 五月月赛 寻宝 exkmp + 主席树
: 寻宝 时间限制: Sec 内存限制: MB 提交: 解决: [提交] [状态] [讨论版] [命题人:admin] 题目描述 采蘑菇的小西佬找到了一张上古年间的藏宝图,上面画着m座连绵不断的山,他 ...
- 【学术篇】CF833B TheBakery 分治dp+主席树
题目の传送门~ 题目大意: 将\(n\)个蛋糕分成恰好\(k\)份, 求每份中包含的蛋糕的种类数之和的最大值. 这题有两种做法. 第一种是线段树优化dp, 我还没有考虑. 另一种就是分治+主席树. 然 ...
- 权值线段树&&可持久化线段树&&主席树
权值线段树 顾名思义,就是以权值为下标建立的线段树. 现在让我们来考虑考虑上面那句话的产生的三个小问题: 1. 如果说权值作为下标了,那这颗线段树里存什么呢? ----- 这颗线段树中, 记录每个值出 ...
- bzoj3207--Hash+主席树
题目大意: 给定一个n个数的序列和m个询问(n,m<=100000)和k,每个询问包含k+2个数字:l,r,b[1],b[2]...b[k],要求输出b[1]~b[k]在[l,r]中是否出现. ...
随机推荐
- EasyJSWebView原理分析
概述 在iOS6之前,native只能调用webiew里的js代码,官方没有提供js调用native方法的接口.到了iOS7,官方提供了JSContext用来与js交互,native和js可以双向调用 ...
- JavaBean中DAO设计模式简介
一.信息系统的开发架构 客户层-------显示层-------业务层---------数据层---------数据库 1.客户层:客户层就是客户端,简单的来说就是浏览器. 2.显示层:JSP/Ser ...
- Swift-(OC中的enumerateObjectsUsingBlock跟Swift的enumerate区别)
OC中使用: NSArray * lists = [NSArray array]; [lists enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUI ...
- 伟大的淘宝IP库的API接口竟然提示503挂掉了
1 淘宝IP库惊现503错误 吃完晚饭,大概6点半了,天色已暗,太阳早就落山了.回到宿舍打开博客一看,傻眼了:博客每篇文章的评论者的地理信息全部处于“正在查询中……”的状态.这神马情况,不会是被淘宝封 ...
- TDDL剖析
前言 在开始讲解淘宝的TDDL(Taobao Distribute Data Layer)技术之前,请允许笔者先吐槽一番.首先要开喷的是淘宝的社区支持做的无比的烂,TaoCode开源社区上面,几乎从来 ...
- 几种常见web 容器比较
1:产品介绍 WebLogic是美国bea公司出品的一个application server确切的说是一个基于j2ee架构的中间件.BEA WebLogic是用于开发.集成.部署和管理大型分布式We ...
- BZOJ 1305 跳舞(二分+网络流)
无法直接构造最大流来解决这个问题,因为题目要求每首舞曲都需要n对男女进行跳舞. 答案又满足单调性,这启发我们二分答案,判断是否满流验证答案. 假设舞曲数目为x时满足条件,那么每个男生和女生都需要跳x次 ...
- 【bzoj1596】[Usaco2008 Jan]电话网络 树形dp
题目描述 Farmer John决定为他的所有奶牛都配备手机,以此鼓励她们互相交流.不过,为此FJ必须在奶牛们居住的N(1 <= N <= 10,000)块草地中选一些建上无线电通讯塔,来 ...
- CSS定义input disabled样式
disabled 属性规定应该禁用 input 元素.被禁用的 input 元素既不可用,也不可点击.可以设置 disabled 属性,直到满足某些其他的条件为止(比如选择了一个复选框等等).然后,就 ...
- [洛谷P4168][Violet]蒲公英
题目大意:有$n(n\leqslant4\times10^4)$个数,$m(m\leqslant5\times10^4)$个询问,每次问区间$[l,r]$内的众数,若相同输出最小的,强制在线. 题解: ...