画方框

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】画方框 [主席树]的更多相关文章

  1. 主席树入门(区间第k大)

    主席树入门 时隔5个月,我又来填主席树的坑了,现在才发现学算法真的要懂了之后,再自己调试,慢慢写出来,如果不懂,就只会按照代码敲,是不会有任何提升的,都不如不照着敲. 所以搞算法一定要弄清原理,和代码 ...

  2. 【BZOJ】1146: [CTSC2008]网络管理Network(树链剖分+线段树套平衡树+二分 / dfs序+树状数组+主席树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1146 第一种做法(时间太感人): 第二种做法(rank5,好开心) ================ ...

  3. BZOJ 4539: [Hnoi2016]树 [主席树 lca]

    4539: [Hnoi2016]树 题意:不想写.复制模板树的子树,查询两点间距离. *** 终于有一道会做的题了...... 画一画发现可以把每次复制的子树看成一个大点来建一棵树,两点的lca一定在 ...

  4. bzoj 4448 [Scoi2015]情报传递 (树链剖分+主席树)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4448 题面: Description 奈特公司是一个巨大的情报公司,它有着庞大的情报网络 ...

  5. 线段树简单入门 (含普通线段树, zkw线段树, 主席树)

    线段树简单入门 递归版线段树 线段树的定义 线段树, 顾名思义, 就是每个节点表示一个区间. 线段树通常维护一些区间的值, 例如区间和. 比如, 上图 \([2, 5]\) 区间的和, 为以下区间的和 ...

  6. 五月月赛 寻宝 exkmp + 主席树

    : 寻宝 时间限制: Sec 内存限制: MB 提交: 解决: [提交] [状态] [讨论版] [命题人:admin] 题目描述 采蘑菇的小西佬找到了一张上古年间的藏宝图,上面画着m座连绵不断的山,他 ...

  7. 【学术篇】CF833B TheBakery 分治dp+主席树

    题目の传送门~ 题目大意: 将\(n\)个蛋糕分成恰好\(k\)份, 求每份中包含的蛋糕的种类数之和的最大值. 这题有两种做法. 第一种是线段树优化dp, 我还没有考虑. 另一种就是分治+主席树. 然 ...

  8. 权值线段树&&可持久化线段树&&主席树

    权值线段树 顾名思义,就是以权值为下标建立的线段树. 现在让我们来考虑考虑上面那句话的产生的三个小问题: 1. 如果说权值作为下标了,那这颗线段树里存什么呢? ----- 这颗线段树中, 记录每个值出 ...

  9. bzoj3207--Hash+主席树

    题目大意: 给定一个n个数的序列和m个询问(n,m<=100000)和k,每个询问包含k+2个数字:l,r,b[1],b[2]...b[k],要求输出b[1]~b[k]在[l,r]中是否出现. ...

随机推荐

  1. 20172330 2017-2018-1 《Java程序设计》第四周学习总结

    20172330 2017-2018-1 <Java程序设计>第四周学习总结 教材学习内容总结 这一周的内容还是比较多的,而且很复杂,包含第四和第七章. 第四章向我们介绍了类结构的定义与概 ...

  2. 3dContactPointAnnotationTool开发日志(三)

      今天的目的是把obj文件导到场景里.具体将制定路径的obj文件导进去我用的是这个方法.导进去后呈现的是一个黑色的影子.   导入后还想实现一下缩放功能,请看这个方法.缩放实现起来也很简单.   光 ...

  3. PokeCats开发者日志(九)

      现在是PokeCats游戏开发的第十五天的中午,总算过了规范性检查这一关. 但愿能过吧.

  4. 网络编程--System.Net

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  5. java基础--逻辑运算符-- 002

    1:int a = 10;int b = 20;boolean flag = (a == b) //falseboolean flag = (a = b) //报错,不兼容的类型 2: &, ...

  6. Sitemesh小记

    一.前言 因参与公司框架改造,接触到了Sitemesh这个用于网页布局和修饰的框架,因之前没有接触过(汗颜),但是发现其小巧好用,便以此文记之~ 二.正文 Sitemesh有什么作用呢?我相信很多人在 ...

  7. MySQL & export

    MySQL & export mysql export table form command line https://cn.bing.com/search?q=mysql%20export% ...

  8. 前端基础:JavaScript对象

    JavaScript对象 在JavaScript中除了null和undefined以外,其他的数据类型都被定义成了对象,也可以用创建对象的方法定义变量,数字型.布尔型.字符串.日期.数字和正则表达式. ...

  9. hdu 1690 Bus System (最短路径)

    Bus System Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  10. JS详细图解全方位解读this

    JS详细图解全方位解读this 对于this指向的理解中,有这样一种说法:谁调用它,this就指向谁.在我刚开始学习this的时候,我是非常相信这句话的.因为在一些情况下,这样理解也还算说得通.可是我 ...