• 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
    ",ans);
    }
  • 相关阅读:
    [转帖]Mootools源码分析03 Hash
    iphone的手势与触摸编程学习笔记
    怎样使项目中的cocos2d默认模板支持ARC内存管理
    xCode4.2下添加TableViewController会出现”Prototype cells“警告
    关于31天App教程示例中一些因SDK版本而出现的问题
    带你掌握二进制SCA检测工具的短板及应对措施
    HDZ城市行深圳站|AIoT时代,如何抓住智联生活的战略机会点?
    分析内部运行机制,教你解决Redis性能问题
    今天谈谈用户故事地图,不是用户故事
    云图说|ModelArts Pro:让AI开发更简单
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5205333.html
Copyright © 2020-2023  润新知