bzoj 3289 莫队 逆序对

 

莫队维护逆序对,区间左右增减要分类讨论。

 

记得离散化。

 

  1 /**************************************************************
  2     Problem: 3289
  3     User: idy002
  4     Language: C++
  5     Result: Accepted
  6     Time:5480 ms
  7     Memory:3164 kb
  8 ****************************************************************/
  9  
 10 #include <cstdio>
 11 #include <cstring>
 12 #include <cmath>
 13 #include <algorithm>
 14 #define maxn 50010
 15 #define lowbit(i) ((i)&(-(i)))
 16 using namespace std;
 17  
 18 typedef long long lng;
 19  
 20 int n, m;
 21 int disc[maxn];
 22 int lx[maxn], rx[maxn], mccno[maxn], stot;
 23 int w[maxn];
 24 lng cnt[maxn], cnttot, cur_ans;
 25 lng ans[maxn];
 26  
 27 struct Qu {
 28     int l, r, id;
 29     bool operator<( const Qu & b ) const {
 30         return mccno[l]<mccno[b.l] || (mccno[l]==mccno[b.l] && r<b.r );
 31     }
 32 };
 33 Qu qu[maxn];
 34  
 35 lng qu_pres( int r ) {  
 36     lng rt = 0;
 37     for( int i=r; i; i-=lowbit(i) )
 38         rt += cnt[i];
 39     return rt;
 40 }
 41 void up_val( int pos, int delta ) {
 42     for( int i=pos; i<=n; i+=lowbit(i) )
 43         cnt[i] += delta;
 44     cnttot += delta;
 45 }
 46 void push_back( int pos ) { 
 47     cur_ans += cnttot - qu_pres( pos );
 48     up_val( pos, +1 );
 49 }
 50 void pop_back( int pos ) {
 51     cur_ans -= cnttot - qu_pres( pos );
 52     up_val( pos, -1 );
 53 }
 54 void push_front( int pos ) {
 55     cur_ans += qu_pres( pos-1 );
 56     up_val( pos, +1 );
 57 }
 58 void pop_front( int pos ) {
 59     cur_ans -= qu_pres( pos-1 );
 60     up_val( pos, -1 );
 61 }
 62  
 63 void partition() {
 64     int len = (int)ceil(sqrt(n))+1;
 65     int stot = n/len;
 66     rx[0] = 0;
 67     for( int i=1; i<=stot; i++ ) {
 68         lx[i] = rx[i-1]+1;
 69         rx[i] = rx[i-1]+len;
 70     }
 71     if( rx[stot]!=n ) {
 72         stot++;
 73         lx[stot] = rx[stot-1]+1;
 74         rx[stot] = n;
 75     }
 76     for( int i=1; i<=stot; i++ ) 
 77         for( int j=lx[i]; j<=rx[i]; j++ )
 78             mccno[j] = i;
 79 }
 80 void work() {
 81     sort( qu+1, qu+1+m );
 82     int lf, rg;
 83     for( int q=1; q<=m; q++ ) {
 84         if( q==1 || mccno[qu[q].l] != mccno[qu[q-1].l] ) {
 85             lf = qu[q].l;
 86             rg = qu[q].l-1;
 87             memset( cnt, 0, sizeof(cnt) );
 88             cur_ans = cnttot = 0;
 89         }
 90         while( lf<qu[q].l ) pop_front( w[lf++] );
 91         while( lf>qu[q].l ) push_front( w[--lf] );
 92         while( rg<qu[q].r ) push_back( w[++rg] );
 93         while( rg>qu[q].r ) pop_back( w[rg--] );
 94         ans[qu[q].id] = cur_ans;
 95     }
 96 }
 97 int main() {
 98     scanf( "%d", &n );
 99     for( int i=1; i<=n; i++ ) {
100         scanf( "%d", w+i );
101         disc[i] = w[i];
102     }
103     sort( disc+1, disc+1+n );
104     for( int i=1; i<=n; i++ )
105         w[i] = lower_bound( disc+1, disc+1+n, w[i] ) - disc;
106     scanf( "%d", &m );
107     for( int i=1; i<=m; i++ ) {
108         scanf( "%d%d", &qu[i].l, &qu[i].r );
109         qu[i].id = i;
110     }
111     partition();
112     work();
113     for( int i=1; i<=m; i++ ) 
114         printf( "%lld\n", ans[i] );
115 }
View Code

 

posted @ 2015-02-23 16:22  idy002  阅读(253)  评论(0编辑  收藏  举报