码迷,mamicode.com
首页 > 其他好文 > 详细

打卡1

时间:2018-09-04 01:47:49      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:main   printf   ref   class   name   --   ||   coloring   ++   

CodeForces 628E  Zbazi in Zeydabad

这个树状数组很巧妙。

将$O(n^3)$降到$O(n^2logn)$。

每个对角线的加和相等,建在一棵树上。

技术分享图片
#include <bits/stdc++.h>
using namespace std;
const int maxn = 3005;
int c[maxn << 1][maxn];
int l[maxn][maxn];
int dig[maxn][maxn];
int r[maxn][maxn];
char s[maxn][maxn];
int n, m;
typedef long long ll;
void add(int id, int x)
{
    while(x <= n)
    {
        c[id][x] += 1;
        x += (x & -x);
    }
}
int sum(int id, int x)
{
    int res = 0;
    while(x > 0)
    {
        res += c[id][x];
         x -= (x & -x);
    }
    return res;
}
int main()
{
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; i++)
    {
        scanf("%s", s[i] + 1);
    }
    /// O(nm)预处理出向左的最长,向左下的最长,还有是不是水平线段的最右点
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            if(s[i][j] == .)
            {
                l[i][j] = 0;
            }
            else if(s[i][j] == z)
            {
                l[i][j] = l[i][j - 1] + 1;
            }
            if(s[i][j + 1] != z)
            {
                r[i][j] = 0;
            }
            else r[i][j] = 1;
        }
    }
    for(int i = n; i >= 1; i--)
    {
        for(int j = 1; j <= m; j++)
        {
            if(s[i][j] == .)
            {
                dig[i][j] = 0;
            }
            else
            {
                dig[i][j] = dig[i + 1][j - 1] + 1;
            }
        }
    }
    ll ans = 0;
    for(int j = m; j >= 1; j--)
    {
        for(int i = 1; i <= n; i++)
        {
            if(s[i][j] == z && r[i][j] == 0)
            {
                int pos = j;
                while(s[i][pos] == z)
                {
                    add(i + pos, i);
                    pos--;
                }
            }
        }
        for(int i = 1; i <= n; i++)
        {
            if(s[i][j] == z) ///枚举右上端点
            {
                ans += sum(i + j, i + min(l[i][j], dig[i][j]) - 1) - sum(i + j, i - 1);
            }
        }
    }
    printf("%lld\n", ans);
    return 0;
}
Code

 

Grid Coloring

写的傻逼样,明天再改吧。

傻逼代码:

技术分享图片
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int dp1[33][33][3];
int dp2[33][33][3];
char s[33][33];
int main()
{
    int n, m; scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; i++)
    {
        scanf("%s", s[i] + 1);
    }
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            if(s[i][j] == B)
            {
                for(int p = 1; p <= i; p++)
                {
                    for(int q = 1; q <= j; q++)
                    {
                        if(s[p][q] == .)
                        {
                            s[p][q] = B;
                        }
                    }
                }
            }
        }
    }
    for(int i = n; i >= 1; i--)
    {
        for(int j = m; j >= 1; j--)
        {
            if(s[i][j] == R)
            {
                for(int p = n; p >= i; p--)
                {
                    for(int q = m; q >= j; q--)
                    {
                        if(s[p][q] == .)
                        {
                            s[p][q] = R;
                        }
                    }
                }
            }
        }
    }
    for(int i = 1; i <= n; i++) printf("%s\n", s[i] + 1);
    if(s[1][1] == B || s[1][1] == .) dp1[1][1][0] = 1;
    if(s[n][m] == R || s[n][m] == .) dp2[n][m][1] = 1;
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)=
        {
            if(i == 1 && j == 1) continue;
            if(s[i][j] == B)
            {
                ///那我就检查是否合法
                int flag = 0;
                if(j > 1 && dp1[i][j - 1][0] == 0) flag = 1;
                if(i > 1 && dp1[i - 1][j][0] == 0) flag = 1;
                if(!flag) dp1[i][j][0] = 1;
                else dp1[i][j][0] = 0;
            }
        }
    }
    for(int i = n; i >= 1; i--)
    {
        for(int j = m; j >= 1; j--)
        {
            if(i == n && j == m) continue;
            if(s[i][j] == R || s[i][j] == .)
            {
                int flag = 0;
                if(i < n && dp2[i + 1][j][1] == 0) flag = 1;
                if(j < m && dp2[i][j + 1][1] == 0) flag = 1;
                if(!flag) dp2[i][j][0] = 1;
                else dp2[i][j][0] = 0;
            }
        }
    }
    int ans = 0;
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {

        }
    }
    printf("%d\n", ans);
    return 0;
}
/*
7 6
......
.....B
.B..R.
......
...B..
......
.R.R..
*/
Code

 

打卡1

标签:main   printf   ref   class   name   --   ||   coloring   ++   

原文地址:https://www.cnblogs.com/littlepear/p/9581879.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!