Educational Codeforces Round 8 E - Zbazi in Zeydabad
2016-04-01 13:26
351 查看
http://codeforces.com/contest/628/problem/E
L[i][j] 表示(i,j)左边连续的‘z’个数
R[i][j] 表示右边
D[i][j] 从左下,向右上 ,连续‘z’的个数
每次求 以 (i,j) 为左上角顶点的 ‘z’的个数:
另 k = min(L[i][j],D[i][j]); 那么 以 (i,j) 为左上角顶点的 ‘z’的个数 最多为k个。
具体有几个? 从(i,j) 向左下角延伸(延伸距离不超过k),得到的每个点(x,y),如果y+R[x][y] > j 则是一个可行解
用树状数组维护 y+R[x][y] > j 的个数。 由于对角线上的点x+y恒定且唯一,因此以x+y 作为某对角线所对应树状数组的编号
L[i][j] 表示(i,j)左边连续的‘z’个数
R[i][j] 表示右边
D[i][j] 从左下,向右上 ,连续‘z’的个数
每次求 以 (i,j) 为左上角顶点的 ‘z’的个数:
另 k = min(L[i][j],D[i][j]); 那么 以 (i,j) 为左上角顶点的 ‘z’的个数 最多为k个。
具体有几个? 从(i,j) 向左下角延伸(延伸距离不超过k),得到的每个点(x,y),如果y+R[x][y] > j 则是一个可行解
用树状数组维护 y+R[x][y] > j 的个数。 由于对角线上的点x+y恒定且唯一,因此以x+y 作为某对角线所对应树状数组的编号
#include<stdio.h> #include<string.h> #include<ctype.h> #include<math.h> #include<string> #include<set> #include<map> #include<vector> #include<queue> #include<algorithm> #include<ctime> using namespace std; void fre(){freopen("t.txt","r",stdin);} template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; } template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; } #define ls o<<1 #define rs o<<1|1 #define MS(x,y) memset(x,y,sizeof(x)) #define debug(x) printf("%d",x); typedef long long LL; typedef unsigned long long UL; typedef unsigned int UI; const int INF = 1<<30; const int MAXN = 105; const double eps = 1e-8; const double pi = acos(-1.0); const LL M = 1e9+7; int n,m,L[3005][3005],R[3005][3005],D[3005][3005],a[6006][3005]; char mp[3005][3005]; LL ans; void add(int y,int x) { while(x <= 3000) { a[y][x]+=1; x+= x&(-x); } } int query(int y,int x) { int ret = 0; while(x > 0) { ret+= a[y][x]; x-=x&(-x); } return ret; } void init() { int i,j; for(i = 1; i <= n; ++i) for(j = 1; j <= m; ++j) if(mp[i][j] == 'z') L[i][j] = L[i][j-1]+1; else L[i][j] = 0; for(i = 1; i <= n; ++i) for(j = m; j > 0; --j) if(mp[i][j] == 'z') R[i][j] = R[i][j+1]+1; else R[i][j] = 0; for(i = n; i > 0; --i) for(j = 1; j <= m; ++j) if(mp[i][j] == 'z') D[i][j] = D[i+1][j-1]+1; else D[i][j] = 0; } void solve() { int i,j,k,x,y; for(j = m; j > 0; --j) { for(i = 1; i <= n; ++i)//维护树状数组 { if(L[i][j+1] || mp[i][j] != 'z') continue; for(y = j; y >= j-L[i][j]+1; --y) add(i+y,y); } for(i = 1; i <= n; ++i)//查询 { if(mp[i][j] != 'z') continue; k = min(L[i][j],D[i][j]); ans+=query(i+j,j) - query(i+j,j-k); } } } int main() { //fre(); ans = 0; scanf("%d%d",&n,&m); for(int i = 1; i <= n; ++i) scanf("%s",mp[i]+1); init(); solve(); printf("%I64d\n",ans); }
相关文章推荐
- Linux下的Input子系统(三)
- 函数指针
- file_get_contents()获取https出现这个错误Unable to find the wrapper “https”
- Ubuntu下U盘文件只读的解决办法
- spark1.6分布式集群环境搭建
- DB2行转列(多维度)
- Bitmap优化及内存优化
- 方法重载,递归,封装
- iOS开发-进阶:设置group类型tableview的section间距
- 在虚拟机中安装红旗桌面7.0 Linux操作系统的详细图文教程
- PHP实例函数:获取淘宝商品价格
- Codeforces VK Cup 2016 - Round 1 (Div. 2 Edition)
- uva 11806(容斥原理)
- mysql索引总结----mysql 索引类型以及创建
- 二维数组和指针
- 机器学习系列之EM算法
- 提高代码质量:如何编写函数 --转载
- 栈——链表实现
- 栈——链表实现
- 站群管理经验之Log日志监控