E. Zbazi in Zeydabad

题目连接:

http://www.codeforces.com/contest/628/problem/D

Description

A tourist wants to visit country Zeydabad for Zbazi (a local game in Zeydabad).

The country Zeydabad is a rectangular table consisting of n rows and m columns. Each cell on the country is either 'z' or '.'.

The tourist knows this country is named Zeydabad because there are lots of ''Z-pattern"s in the country. A ''Z-pattern" is a square which anti-diagonal is completely filled with 'z' and its upper and lower rows are also completely filled with 'z'. All other cells of a square can be arbitrary.

Note that a ''Z-pattern" can consist of only one cell (see the examples).

So he wants to count the number of ''Z-pattern"s in the country (a necessary skill for Zbazi).

Now your task is to help tourist with counting number of ''Z-pattern"s.

As input/output can reach huge size it is recommended to use fast input/output methods: for example, prefer to use gets/scanf/printf instead of getline/cin/cout in C++, prefer to use BufferedReader/PrintWriter instead of Scanner/System.out in Java.

Input

The first line contains two integers n, m (1 ≤ n, m ≤ 3000) — the number of rows and columns respectively.

Each of the next n lines contains m characters 'z' or '.' — the description of Zeydabad.

Output

Print the only integer a — the number of ''Z-pattern"s in Zeydabad.

Sample Input

4 4

zzzz

zzz.

.z..

zzzz

Sample Output

16

Hint

题意

给你一个n*m的矩阵,然后问你里面有多少个z

题解:

数据结构

首先我们对于每一个点维护一个l[i][j],r[i][j],表示这个点往左边最多延伸多少,往右边最多延伸多少

我们去维护每一个对角线就好了,我们从左下角跑到右上角

我们update(i,1)表示这个位置当前是可以的,他对于上面的i+r[i][j]-1个都是可以更新的

他这个点的贡献就是query(i)-query(i-len),len = l[i][j]和i-last的最小值,显然他可以和下面len个进行组合

然后这样去跑就好了

我讲的比较抽象,还是看代码吧……

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 3e3+5;
int a[maxn],n,m;
char s[maxn][maxn];
int l[maxn][maxn],r[maxn][maxn];
vector<int>over[maxn];
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int val)
{
x++;
for(int i=x;i<maxn;i+=lowbit(i))
a[i]+=val;
}
int query(int x)
{
x++;
int ans=0;
for(int i=x;i;i-=lowbit(i))
ans+=a[i];
return ans;
}
long long solve(int x,int y)
{
memset(a,0,sizeof(a));
int L = min(m-y,x+1);
for(int i=0;i<maxn;i++)over[i].clear();
int last=-1;
long long ret = 0;
for(int i=0;i<L;i++)
{
int nx = x-i;
int ny = y+i;
if(s[nx][ny]=='.')
last=i;
else{
update(i,1);over[i+r[nx][ny]-1].push_back(i);
int len = min(l[nx][ny],i-last);
ret+=query(i)-query(i-len);
}
for(int j=0;j<over[i].size();j++)
update(over[i][j],-1);
}
return ret;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
scanf("%s",s[i]);
for(int i=0;i<n;i++)
{
l[i][0]=s[i][0]=='z';
for(int j=1;j<m;j++)
if(s[i][j]=='z')l[i][j]=l[i][j-1]+1;
r[i][m-1]=s[i][m-1]=='z';
for(int j=m-2;j>=0;j--)
if(s[i][j]=='z')r[i][j]=r[i][j+1]+1;
}
long long ans = 0;
for(int i=0;i<n;i++)
ans+=solve(i,0);
for(int i=1;i<m;i++)
ans+=solve(n-1,i);
printf("%lld\n",ans);
}

Educational Codeforces Round 8 E. Zbazi in Zeydabad 树状数组的更多相关文章

  1. CF Educational Codeforces Round 10 D. Nested Segments 离散化+树状数组

    题目链接:http://codeforces.com/problemset/problem/652/D 大意:给若干个线段,保证线段端点不重合,问每个线段内部包含了多少个线段. 方法是对所有线段的端点 ...

  2. Educational Codeforces Round 10 D. Nested Segments 离线树状数组 离散化

    D. Nested Segments 题目连接: http://www.codeforces.com/contest/652/problem/D Description You are given n ...

  3. Educational Codeforces Round 10 D. Nested Segments 【树状数组区间更新 + 离散化 + stl】

    任意门:http://codeforces.com/contest/652/problem/D D. Nested Segments time limit per test 2 seconds mem ...

  4. Codeforces 628E Zbazi in Zeydabad 树状数组

    题意:一个n*m的矩阵,要么是 . 要么是 z ,问可以形成几个大z 分析:(直接奉上官方题解,我感觉说的实在是太好了) Let's precalculate the values zlij, zri ...

  5. Codeforces Round #401 (Div. 1) C(set+树状数组)

    题意: 给出一个序列,给出一个k,要求给出一个划分方案,使得连续区间内不同的数不超过k个,问划分的最少区间个数,输出时将k=1~n的答案都输出 比赛的时候想的有点偏,然后写了个nlog^2n的做法,T ...

  6. Educational Codeforces Round 40 G. Castle Defense (二分+滑动数组+greedy)

    G. Castle Defense time limit per test 1.5 seconds memory limit per test 256 megabytes input standard ...

  7. Codeforces 703D Mishka and Interesting sum(树状数组+扫描线)

    [题目链接] http://codeforces.com/contest/703/problem/D [题目大意] 给出一个数列以及m个询问,每个询问要求求出[L,R]区间内出现次数为偶数的数的异或和 ...

  8. CodeForces 380C Sereja and Brackets(扫描线+树状数组)

    [题目链接] http://codeforces.com/problemset/problem/380/C [题目大意] 给出一个括号序列,求区间内左右括号匹配的个数. [题解] 我们发现对于每个右括 ...

  9. Codeforces 703D Mishka and Interesting sum 离线+树状数组

    链接 Codeforces 703D Mishka and Interesting sum 题意 求区间内数字出现次数为偶数的数的异或和 思路 区间内直接异或的话得到的是出现次数为奇数的异或和,要得到 ...

随机推荐

  1. python自动开发之第二十二天

    知识点概要 - Session - CSRF - Model操作 - Form验证(ModelForm) - 中间件 - 缓存 - 信号 一. Session 基于Cookie做用户验证时:敏感信息不 ...

  2. python—RE正则表达式

    re正则表达式 正则表达式(或 RE)是一种小型的.高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现.正则表达式模式被编译成一系列的字节码,然后由用 C 编写的 ...

  3. FC4-i386-SRPMS

    [重点] http://archives.fedoraproject.org/pub/archive/fedora/linux/core/6/ http://archives.fedoraprojec ...

  4. sicily 数据结构 1014. Translation

    Description You have just moved from Waterloo to a big city. The people here speak an incomprehensib ...

  5. Vim配置Node.js开发工具

    ubuntu安装vim编辑器.默认情况下,vim在运行的时候会加载-/.vimrc文件里的配置文件,如果在-目录下不存在这个配置文件可以手动创建. 在-/.vim目录下是vim的插件加载的位置,可以在 ...

  6. C++11空指针: nullptr

    参考[C++11]新特性--引入nullptr NULL 在C++中, 经常会用到空指针, 一般用NULL表示空指针, 但是NULL却是这样定义的 #ifndef NULL #ifdef __cplu ...

  7. hdu 1547(BFS)

    Bubble Shooter Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  8. (翻译)Xamarin.Essentials 最新预览版的更多跨平台 API

    原文地址:https://blog.xamarin.com/cross-platform-apis-xamarin-essentials-latest-preview/ 在 Microsoft Bui ...

  9. OpenStack 认证服务 KeyStone 服务注册(六)

    一)检查keystone是否安装配置成功 1.1删除环境变量的配置 unset OS_AUTH_URL redhat 1.2 请求令牌认证 admin用户,请求认证令牌 openstack --os- ...

  10. C语言数据类型64位和32机器的区别

    C语言编程需要注意的64位和32机器的区别 .数据类型特别是int相关的类型在不同位数机器的平台下长度不同.C99标准并不规定具体数据类型的长度大小,只规定级别.作下比较: 32位平台 char:1字 ...