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

hdu 4391 块状链表区间操作lazy技巧

时间:2015-05-02 16:28:06      阅读:125      评论:0      收藏:0      [点我收藏+]

标签:

块状链表太强大了,也可以实现和线段树一样的lazy操作来提高效率。

每个块维护自己块的信息。

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <cmath>
  5 #include <map>
  6 using namespace std;
  7 
  8 const int M = 400;
  9 int b[M][M];
 10 int n, m, ps;
 11 int lazy[M];
 12 map<int, int> mp[M];
 13 
 14 void down( int i )
 15 {
 16     if ( lazy[i] == -1 ) return ;
 17     for ( int j = 0; j < ps && i * ps + j < n; j++ )
 18     {
 19         b[i][j] = lazy[i];
 20     }
 21     lazy[i] = -1;
 22 }
 23 
 24 int query( int l, int r, int v )
 25 {
 26     int cur = l / ps, ncur = r / ps;
 27     l = l % ps, r = r % ps;
 28     int res = 0;
 29     for ( int i = cur + 1; i < ncur; i++ )
 30     {
 31         if ( mp[i].count(v) )
 32         {
 33             res += mp[i][v];
 34         }
 35     }
 36     if ( cur != ncur )
 37     {
 38         down(cur);
 39         for ( int j = l; j < ps; j++ )
 40         {
 41             if ( b[cur][j] == v ) res++;
 42         }
 43         down(ncur);
 44         for ( int j = 0; j <= r; j++ )
 45         {
 46             if ( b[ncur][j] == v ) res++;
 47         }
 48     }
 49     else
 50     {
 51         down(cur);
 52         for ( int j = l; j <= r; j++ )
 53         {
 54             if ( b[cur][j] == v ) res++;
 55         }
 56     }
 57     return res;
 58 }
 59 
 60 void update( int l, int r, int v )
 61 {
 62     int cur = l / ps, ncur = r / ps;
 63     l = l % ps, r = r % ps;
 64     for ( int i = cur + 1; i < ncur; i++ )
 65     {
 66         mp[i].clear();
 67         mp[i][v] = ps;
 68         lazy[i] = v;
 69     }
 70     if ( cur != ncur )
 71     {
 72         down(cur);
 73         for ( int j = l; j < ps; j++ )
 74         {
 75             mp[cur][b[cur][j]]--;
 76             b[cur][j] = v;
 77         }
 78         mp[cur][v] += ps - l;
 79         down(ncur);
 80         for ( int j = 0; j <= r; j++ )
 81         {
 82             mp[ncur][b[ncur][j]]--;
 83             b[ncur][j] = v;
 84         }
 85         mp[ncur][v] += r + 1;
 86     }
 87     else
 88     {
 89         down(cur);
 90         for ( int j = l; j <= r; j++ )
 91         {
 92             mp[cur][b[cur][j]]--;
 93             b[cur][j] = v;
 94         }
 95         mp[cur][v] += r - l + 1;
 96     }
 97 }
 98 
 99 int main ()
100 {
101     ps = 350;
102     while ( scanf("%d%d", &n, &m) != EOF )
103     {
104         memset( lazy, -1, sizeof(lazy) );
105         for ( int i = 0; i < M; i++ ) mp[i].clear();
106         for ( int i = 0; i < n; i++ )
107         {
108             int tmp;
109             scanf("%d", &tmp);
110             b[i / ps][i % ps] = tmp;
111             mp[i / ps][tmp]++;
112         }
113         int a, l, r, z;
114         while ( m-- )
115         {
116             scanf("%d%d%d%d", &a, &l, &r, &z);
117             if ( a == 1 )
118             {
119                 update( l, r, z );
120             }
121             else
122             {
123                 printf("%d\n", query( l, r, z ));
124             }
125         }
126     }
127     return 0;
128 }

 

hdu 4391 块状链表区间操作lazy技巧

标签:

原文地址:http://www.cnblogs.com/huoxiayu/p/4472112.html

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