zoukankan      html  css  js  c++  java
  • bzoj 3809 莫队

    收获:

      1、分块时顺便记录每个位置所属的块,然后一次排序就OK了。

      2、要权衡在“区间移动”与“查询结果”之间的时间,莫队算法一般区间移动频率远大于查询结果,所以我们选择的辅助数据结构时就要注意了,我最开始写的是值域线段树,自己生成的极限数据要1m8s,改成树状数组后要24s,还是过不了,hzwer只要13s,细看hzwer的代码,发现Ta用的是分块,O(1)修改O(n0.5)查询,改成分块后的确快多了。

      3、块的大小理论最优值是O(n*m-0.5),最开始设成这个交上去35卡过,改成hzwer的n/2后29s,所以做题时要自己试一下。

      1 /**************************************************************
      2     Problem: 3809
      3     User: idy002
      4     Language: C++
      5     Result: Accepted
      6     Time:29336 ms
      7     Memory:26988 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <cctype>
     12 #include <cstring>
     13 #include <cmath>
     14 #include <algorithm>
     15 #define maxn 100010
     16 #define maxm 1000010
     17 #define lowbit(i) ((i)&(-(i)))
     18 using namespace std;
     19  
     20  
     21 int n, m;
     22 int lx[maxn], rx[maxn], mccno[maxn], stot;
     23 int w[maxn];
     24 int ans[maxm];
     25 int cnt[maxn], siz[maxn], cmc[maxn];
     26  
     27  
     28 struct Qu {
     29     int l, r, a, b, id;
     30     bool operator<( const Qu & c ) const {
     31         return mccno[l]<mccno[c.l] || ( mccno[l]==mccno[c.l] && r<c.r );
     32     }
     33 };
     34 Qu qu[maxm];
     35  
     36 void add( int pos ) {
     37     siz[pos]++;
     38     if( siz[pos]==1 ) cmc[mccno[pos]]++;
     39 }
     40 void del( int pos ) {
     41     siz[pos]--;
     42     if( siz[pos]==0 ) cmc[mccno[pos]]--;
     43 }
     44 int query( int l, int r ) {
     45     int lm = mccno[l], rm = mccno[r];
     46     int rt = 0;
     47     if( lm==rm ) {
     48         for( int j=l; j<=r; j++ )
     49             if( siz[j] ) rt++;
     50         return rt;
     51     }
     52     for( int b=lm+1; b<rm; b++ )
     53         rt += cmc[b];
     54     for( int j=l; j<=rx[lm]; j++ )
     55         if( siz[j] ) rt++;
     56     for( int j=lx[rm]; j<=r; j++ )
     57         if( siz[j] ) rt++;
     58     return rt;
     59 }
     60 void partition() {
     61     int len = (int)ceil(sqrt(n/2)+1);
     62     stot = n/len;
     63     rx[0] = 0;
     64     for( int i=1; i<=stot; i++ ) {
     65         lx[i] = rx[i-1]+1;
     66         rx[i] = rx[i-1]+len;
     67     }
     68     if( rx[stot]!=n ) {
     69         stot++;
     70         lx[stot] = rx[stot-1]+1;
     71         rx[stot] = n;
     72     }
     73     for( int i=1; i<=stot; i++ ) 
     74         for( int j=lx[i]; j<=rx[i]; j++ )
     75             mccno[j] = i;
     76 }
     77 void work() {
     78     sort( qu+1, qu+1+m);
     79  
     80     int lf = qu[1].l;
     81     int rg = qu[1].r;
     82     for( int j=lf; j<=rg; j++ )
     83         add(w[j]);
     84     ans[qu[1].id] = query( qu[1].a, qu[1].b );
     85     for( int q=2; q<=m; q++ ) {
     86         while( qu[q].l<lf ) add(w[--lf]);
     87         while( qu[q].l>lf ) del(w[lf++]);
     88         while( qu[q].r>rg ) add(w[++rg]);
     89         while( qu[q].r<rg ) del(w[rg--]);
     90         ans[qu[q].id] = query( qu[q].a, qu[q].b );
     91     }
     92 }
     93 int main() {
     94     scanf( "%d%d", &n, &m );
     95     for( int i=1; i<=n; i++ )
     96         scanf( "%d", w+i );
     97     for( int i=1; i<=m; i++ ) {
     98         scanf( "%d%d%d%d", &qu[i].l, &qu[i].r, &qu[i].a, &qu[i].b );
     99         qu[i].id = i;
    100     }
    101     partition();
    102     work();
    103     for( int i=1; i<=m; i++ ) 
    104         printf( "%d
    ", ans[i] );
    105 }
    View Code
  • 相关阅读:
    mac上配置apidoc环境
    Yii 2.0 GII 访问404错误
    yii框架下使用redis
    PHPEXCEL读出数据是PHPExcel_RichText类型
    php实现仿百度分页
    apache的.htaccess文件作用和相关配置
    Yii2.0 解决“the requested URL was not found on this server”问题
    [基础与理论]C#变量
    基础&理论]C#的基本语法
    [基础&理论]C#的含义
  • 原文地址:https://www.cnblogs.com/idy002/p/4297998.html
Copyright © 2011-2022 走看看