• 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
    ",getnum(l,r,d,p));
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    ASP.NET中读取Excel内容,并显示在界面上
    SQL SERVER 的 CLR表值函数
    nowrap要与回车换行符结合才有意义
    何时使用 FILESTREAM?
    case 用在 UPDATE
    查看分区在哪个文件组
    C#里面的随机对象Random
    CLR程序里引用System.Web.dll
    不用写成 if @i=1 OR @i=2 OR ... 这么蠢
    SQL SERVER定期转移海量数据方案
  • 原文地址:https://www.cnblogs.com/zhurb/p/5933326.html
Copyright © 2020-2023  润新知