HDU_5057_分块

Posted 冷暖知不知

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU_5057_分块相关的知识,希望对你有一定的参考价值。

http://acm.hdu.edu.cn/showproblem.php?pid=5057

 

分块,保存每个块中每位对应数字的和,复杂的是getmum,左右下标所在的块不能直接读取block数组,要重新自己计算。

 

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;

int a[100005],belong[100005],L[100005],R[100005],block[400][11][10],n,m;
int ten[11] = {0,1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};

void build()
{
    int sizee = sqrt(n);
    int num = n/sizee;
    if(n%sizee)  num++;
    for(int i = 1;i <= num;i++)
    {
        L[i] = (i-1)*sizee+1;
        R[i] = i*sizee;
    }
    for(int i = 1;i <= n;i++)   belong[i] = (i-1)/sizee+1;
    for(int i = 1;i <= n;i++)
    {
        int temp = a[i];
        for(int j = 1;j <= 10;j++)
        {
            block[belong[i]][j][temp%10]++;
            temp /= 10;
        }
    }
}

int getnum(int l,int r,int d,int p)
{
    int ans = 0;
    if(belong[l] == belong[r])
    {
        for(int i = l;i <= r;i++)
        {
            if((a[i]/ten[d])%10 == p) ans++;
        }
        return ans;
    }

    for(int i = belong[l]+1;i < belong[r];i++)  ans += block[i][d][p];
    for(int i = l;i <= R[belong[l]];i++)
    {
        if((a[i]/ten[d])%10 == p) ans++;
    }
    for(int i = L[belong[r]];i <= r;i++)
    {
        if((a[i]/ten[d])%10 == p) ans++;
    }
    return ans;
}

void update(int x,int y)
{
    for(int i = 1;i <= 10;i++)
    {
        block[belong[x]][i][a[x]%10]--;
        a[x] /= 10;
    }
    a[x] = y;
    for(int i = 1;i <= 10;i++)
    {
        block[belong[x]][i][y%10]++;
        y /= 10;
    }
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(block,0,sizeof(block));
        scanf("%d%d",&n,&m);
        for(int i = 1;i <= n;i++)   scanf("%d",&a[i]);
        build();
        char s[5];
        while(m--)
        {
            scanf("%s",s);
            if(s[0] == S)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                update(x,y);
            }
            else
            {
                int l,r,d,p;
                scanf("%d%d%d%d",&l,&r,&d,&p);
                printf("%d\n",getnum(l,r,d,p));
            }
        }
    }
    return 0;
}

 

以上是关于HDU_5057_分块的主要内容,如果未能解决你的问题,请参考以下文章

HDU 6333 莫队分块 + 逆元打表求组合数

2020杭电HDU-6756多校第一场Finding a MEX(图的分块)

HDU 5057

[CQOI2007]余数求和-整除分块

hdu 1754 I Hate It(分块做法)

HYSBZ_2002_分块