zoukankan      html  css  js  c++  java
  • hdu5057 Argestes and Sequence 分块

    Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 857    Accepted Submission(s): 240
    
    
    Problem Description
    Argestes has a lot of hobbies and likes solving query problems especially. One day Argestes came up with such a problem. You are given a sequence a consisting of N nonnegative integers, a[1],a[2],...,a[n].Then there are M operation on the sequence.An operation can be one of the following:
    S X Y: you should set the value of a[x] to y(in other words perform an assignment a[x]=y).
    Q L R D P: among [L, R], L and R are the index of the sequence, how many numbers that the Dth digit of the numbers is P.
    Note: The 1st digit of a number is the least significant digit.
     
    
    Input
    In the first line there is an integer T , indicates the number of test cases.
    For each case, the first line contains two numbers N and M.The second line contains N integers, separated by space: a[1],a[2],...,a[n]—initial value of array elements.
    Each of the next M lines begins with a character type.
    If type==S,there will be two integers more in the line: X,Y.
    If type==Q,there will be four integers more in the line: L R D P.
    
    [Technical Specification]
    1<=T<= 50
    1<=N, M<=100000
    0<=a[i]<=231 - 1
    1<=X<=N
    0<=Y<=231 - 1
    1<=L<=R<=N
    1<=D<=10
    0<=P<=9
     
    
    Output
    For each operation Q, output a line contains the answer.
     
    
    Sample Input
    1
    5 7
    10 11 12 13 14
    Q 1 5 2 1
    Q 1 5 1 0
    Q 1 5 1 1
    Q 1 5 3 0
    Q 1 5 3 1
    S 1 100
    Q 1 5 3 1
     
    
    Sample Output
    5
    1
    1
    5
    0
    1
     
    
    Source
    BestCoder Round #11 (Div. 2)
     
    之前用线段树一直MLE(在码之前看了下内存限制,就觉得会开不下的了),知道可以用分块做之后,就看了下大白的一道分块题,再想这道题就比较简单了
    ~num[b][a][b]表示第b块所有的数在第a位为b的个数,这些都可以简单预处理出来,然后只是单点修改,把原来的值和新值对比一下更新一下就好了
    #include <bits/stdc++.h>
    
    using namespace std;
    const int N = 1e5 + 10;
    const int SIZE = 330;
    int n, m;
    int A[N];
    int block[N / SIZE + 1][SIZE + 1];
    int num[N / SIZE + 1][12][10];
    void pre(int b, int j)
    {
        int *B = &block[b][0];
        for(int i = 0; i < j; ++i) {
            int tmp = B[i];
            int cnt = 1;
            while(cnt <= 10) {
                int x = tmp % 10;
                tmp /= 10;
                num[b][cnt][x]++;
                cnt++;
            }
        }
    }
    void init()
    {
        memset(num, 0, sizeof num);
        scanf("%d%d", &n, &m);
        int j = 0, b = 0;
        for(int i = 0; i < n; ++i) {
            scanf("%d", &A[i]);
            block[b][j] = A[i];
            if(++j == SIZE) {
                pre(b, j);
                b++; j = 0;
            }
        }
        if(j) { pre(b, j); ++b; }
    }
    int get(int x, int d) {
        int cnt = 1;
        while(cnt < d) {
            x /= 10;
            cnt++;
        }
        return x % 10;
    }
    int query(int L, int R, int D, int p)
    {
        int res = 0;
        int lb = L / SIZE, rb = R / SIZE;
        if(lb == rb) {
            for(int i = L; i <= R; ++i) {
                if(get(A[i], D) == p) res++;
            }
        }
        else {
            for(int i = L; i < (lb + 1) * SIZE; ++i) if(get(A[i], D) == p) res++;
            for(int i = rb * SIZE; i <= R; ++i) if(get(A[i], D) == p) res++;
            for(int i = lb + 1; i < rb; ++i) res += num[i][D][p];
        }
        return res;
    }
    void modify(int x, int y)
    {
        if(A[x] == y) return;
        int old = A[x], now = y, b = x / SIZE, cnt = 1;
        int c1[12], c2[12];
        A[x] = y;
        while(cnt <= 10) {
            c1[cnt] = old % 10;
            c2[cnt] = now % 10;
            old /= 10;
            now /= 10;
            cnt++;
        }
        for(int i = 1; i <= 10; ++i) {
            if(c1[i] != c2[i]) {
                num[b][i][ c2[i] ]++;
                num[b][i][ c1[i] ]--;
            }
        }
    }
    int main()
    {
        int _; scanf("%d", &_);
        while(_ --)
        {
            init();
            char op[2];
            int L, R, D, P;
            while(m --)
            {
                scanf("%s", op);
                if(op[0] == 'Q') {
                    scanf("%d%d%d%d", &L, &R, &D, &P);
                    L--; R--;
                    printf("%d
    ", query(L, R, D, P));
                }else {
                    scanf("%d%d", &D, &P);
                    D--;
                    modify(D, P);
                }
            }
        }
        return 0;
    }
      
    
     
  • 相关阅读:
    .netCore+Vue 搭建的简捷开发框架 (5)
    .netCore+Vue 搭建的简捷开发框架 (4)--NetCore 基础 -2
    Vue 学习笔记
    .netCore+Vue 搭建的简捷开发框架 (4)--NetCore 基础
    .netCore+Vue 搭建的简捷开发框架 (3)-- Services层实现
    .netCore+Vue 搭建的简捷开发框架 (2)--仓储层实现和EFCore 的使用
    .netCore+Vue 搭建的简捷开发框架
    在线.net C#和vb.net 语言互转
    VB.net 通过句柄操作其他窗口
    vb.net 多线程爬虫抓取免费代理IP
  • 原文地址:https://www.cnblogs.com/orchidzjl/p/4906955.html
Copyright © 2011-2022 走看看