Educational Codeforces Round 8 E. Zbazi in Zeydabad 树状数组
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 树状数组的更多相关文章
- CF Educational Codeforces Round 10 D. Nested Segments 离散化+树状数组
题目链接:http://codeforces.com/problemset/problem/652/D 大意:给若干个线段,保证线段端点不重合,问每个线段内部包含了多少个线段. 方法是对所有线段的端点 ...
- Educational Codeforces Round 10 D. Nested Segments 离线树状数组 离散化
D. Nested Segments 题目连接: http://www.codeforces.com/contest/652/problem/D Description You are given n ...
- 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 ...
- Codeforces 628E Zbazi in Zeydabad 树状数组
题意:一个n*m的矩阵,要么是 . 要么是 z ,问可以形成几个大z 分析:(直接奉上官方题解,我感觉说的实在是太好了) Let's precalculate the values zlij, zri ...
- Codeforces Round #401 (Div. 1) C(set+树状数组)
题意: 给出一个序列,给出一个k,要求给出一个划分方案,使得连续区间内不同的数不超过k个,问划分的最少区间个数,输出时将k=1~n的答案都输出 比赛的时候想的有点偏,然后写了个nlog^2n的做法,T ...
- 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 ...
- Codeforces 703D Mishka and Interesting sum(树状数组+扫描线)
[题目链接] http://codeforces.com/contest/703/problem/D [题目大意] 给出一个数列以及m个询问,每个询问要求求出[L,R]区间内出现次数为偶数的数的异或和 ...
- CodeForces 380C Sereja and Brackets(扫描线+树状数组)
[题目链接] http://codeforces.com/problemset/problem/380/C [题目大意] 给出一个括号序列,求区间内左右括号匹配的个数. [题解] 我们发现对于每个右括 ...
- Codeforces 703D Mishka and Interesting sum 离线+树状数组
链接 Codeforces 703D Mishka and Interesting sum 题意 求区间内数字出现次数为偶数的数的异或和 思路 区间内直接异或的话得到的是出现次数为奇数的异或和,要得到 ...
随机推荐
- Linux汇编教程02:编写第一个汇编程序
学习一门语言,最好的方式就是在运用中学习,那么在这一章节中,我们开始编写我们的第一个汇编程序.当然作为第一个程序,其实十分的简单,但可以给大家一个基本的轮廓,了解汇编大概是这样的. 我们这个程序实际上 ...
- xtrabackup 安装、备份和恢复
xtrabackup 版本对应: 2.4 专针对 5.7 开发的,兼容 5.6, 5.5 2.3 针对 5.6 开发的,兼容5.5 2.2 针对5.5 开发的 安装包下载: wget https:// ...
- php文件读取的问题
PHP字符编码问题 首先说下字符编码问题,当我们给定路径后如果路径中包含中文,可能会出现问题,打印到屏幕则显示没问题, 但是读取文件会报错:readfile(E:/素玄文件/app历史版本/素玄ERP ...
- centos创建子用户
#adduser 用户名 #passwd 用户名 设置自己的密码即可 授权 个人用户的权限只可以在本home下有完整权限,其他目录要看别人授权.而经常需要root用户的权限,这时候sudo可以化身为r ...
- Java之CyclicBarrier使用
http://blog.csdn.net/shihuacai/article/details/8856407 1.类说明: 一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (commo ...
- 《深入浅出MyBatis技术原理与实战》——1.简介,2.入门
1. 简介 Java程序都是通过JDBC连接数据库,但是只定义了接口规范,具体的实现交给各个数据库厂商去实现,因为每个数据库都有其特殊性.所以JDBC是一种桥接模式. 这里为什么说JDBC是一种桥接模 ...
- Asp.net网页中DataGridView数据导出到Excel
经过上网找资料,终于找到一种可以直接将GridView中数据导出到Excel文件的方法,归纳方法如下: 1. 注:其中的字符集格式若改为“GB2312”,导出的部分数据可能为乱码: 导出之前需要关闭分 ...
- 遇见Python.h: No such file or directory的解决方法
出现No such file or directory的错误,有两种情况,一种是没有Python.h这个文件,一种是Python的版本不对, 可以进入/usr/include/文件夹下的Pythonx ...
- 将xml文件转为c#对像
读取xml文件数据,通过序列化反序列化转为List<T>对象后,对对象进行操作.
- 自动选择profile
cobbler system list cobbler profile list 方式一:自动选择profile cobbler system add --name="linux-node1 ...