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): 1279    Accepted Submission(s): 373


    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
     
    分块大法,降低暴力的时间复杂度
      1 //2016.8.13 
      2 #include<iostream>
      3 #include<cstdio>
      4 #include<cstring>
      5 
      6 using namespace std;
      7 
      8 const int N = 100005;
      9 int a[N], len = 400, n, mi[15] = {0, 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
     10 
     11 struct node
     12 {
     13     int cnt[12][12];//cnt[d][p]表示每个块内第d位是p的个数
     14 }block[400];
     15 
     16 bool judge(int x, int d, int p)//判断x的第d位是否为p
     17 {
     18     return x/mi[d]%10==p;
     19 }
     20 
     21 int query(int l, int r, int d, int p)
     22 {
     23     int id1 = l/len, id2 = r/len, ans = 0;
     24     if(id1==id2)//如果l,r在同一个块内,暴力枚举
     25     {
     26         for(int i = l; i <= r; i++)
     27               if(judge(a[i], d, p))
     28                   ans++;
     29     }else
     30     {
     31         for(int i = id1+1; i <= id2-1; i++)//把中间的块加起来
     32           ans+=block[i].cnt[d][p];
     33         for(int i = l; i <= (id1+1)*len && i <= n; i++)//暴力最左边的块
     34           if(judge(a[i], d, p))
     35             ans++;
     36         for(int i = id2*len+1; i <= r; i++)//暴力最右边的块
     37           if(judge(a[i], d, p))
     38             ans++;
     39     }
     40     return ans;
     41 }
     42 
     43 void update(int x, int y)
     44 {
     45     int tmp = a[x], id = (x-1)/len;//这里起初x少减了个1,WA了好多次忧伤。。。
     46     a[x] = y;
     47     for(int i = 1; i <= 10; i++)
     48     {
     49         block[id].cnt[i][tmp%10]--;
     50         tmp/=10;
     51     }
     52     tmp = a[x];
     53     for(int i = 1; i <= 10; i++)
     54     {
     55         block[id].cnt[i][tmp%10]++;
     56         tmp/=10;
     57     }
     58 }
     59 
     60 int main()
     61 {
     62     int T, d, p, m, x, y, l, r, id;
     63     char cmd;
     64     cin>>T;
     65     while(T--)
     66     {
     67         scanf("%d%d", &n, &m);
     68         memset(block, 0, sizeof(block));
     69         memset(a, 0, sizeof(a));
     70         for(int i = 1; i <= n; i++)
     71         {
     72             scanf("%d", &a[i]);
     73             id = (i-1)/len;
     74             int tmp = a[i];
     75             for(int j = 1; j <= 10; j++)//初始化块
     76             {
     77                 block[id].cnt[j][tmp%10]++;
     78                 tmp/=10;
     79             }
     80         }
     81         while(m--)
     82         {
     83             getchar();
     84             scanf("%c", &cmd);
     85             if(cmd == 'Q')
     86             {
     87                 int ans = 0;
     88                 scanf("%d%d%d%d", &l, &r, &d, &p);
     89                 ans = query(l, r, d, p);
     90                 printf("%d
    ", ans);
     91             }else
     92             {
     93                 scanf("%d%d", &x, &y);
     94                 update(x, y);
     95             }
     96         }
     97     }
     98 
     99     return 0;
    100 }
     
  • 相关阅读:
    JDBC_JDBCUtils2.0
    《Fast Approximate Anti-Aliasing (FXAA) (GLSL)》
    《为什么在多核处理器下需要内存屏障(MenmoryBarrier)?》
    《LINUX KERNEL MEMORY BARRIERS》
    《内存对齐与回调函数参数》
    《Anti-aliasing》
    《Deferred Shading》
    《Bloom》
    《Gamma校正》
    《HDR》
  • 原文地址:https://www.cnblogs.com/Penn000/p/5776567.html
Copyright © 2011-2022 走看看