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 }