1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
| #include "iostream" #include "algorithm" #include "cstring" #include "cstdio" #include "cmath" #include "vector" #include "map" #include "set" #include "bitset" #include "queue" using namespace std; #define MAXN 200006
#define rep(i, a, b) for (int i = (a), i##end = (b); i <= i##end; ++i) #define per(i, a, b) for (int i = (a), i##end = (b); i >= i##end; --i) #define pii pair<int,int> #define fi first #define se second #define mp make_pair #define pb push_back #define eb emplace_back #define vi vector<int> #define all(x) (x).begin() , (x).end() #define mem( a ) memset( a , 0 , sizeof a ) #define P 1000000007 typedef long long ll; int n , m , blo; int A[MAXN] , a[MAXN] , bl[MAXN];
struct que { int l , r , id; inline void rd( int x ) { id = x; scanf("%d%d",&l,&r); } } Q[MAXN] ;
long long ans[MAXN]; long long Ls[MAXN] , Rs[MAXN];
namespace fwk { int T[MAXN]; void add( int x , int c ) { while( x <= n ) T[x] += c , x += ( x & -x ); } int sum( int x ) { int ret = 0; while( x > 0 ) ret += T[x] , x -= ( x & -x ); return ret; } }
int BLO; namespace kuai1 { int T[MAXN] , lz[400]; void add( int x ) { per( i , x , ( x - 1 ) / BLO * BLO + 1 ) ++ T[i]; per( i , ( x - 1 ) / BLO , 1 ) ++ lz[i]; } int get( int x ) { return T[x] + lz[( x - 1 ) / BLO + 1]; } }
namespace kuai2 { int T[MAXN] , lz[400] , tot; void add( int x ) { rep( i , x , ( x - 1 ) / BLO * BLO + BLO ) ++ T[i]; rep( i , ( x - 1 ) / BLO + 2 , tot ) ++ lz[i]; } int get( int x ) { return T[x] + lz[( x - 1 ) / BLO + 1]; } }
struct dq { int l , r , id , c; }; vector<dq> Rqs[MAXN] , Lqs[MAXN];
bool cmp( que a , que b ) { return bl[a.l] == bl[b.l] ? bl[a.l] & 1 ? a.r < b.r : a.r > b.r : a.l < b.l; }
void solve() { cin >> n >> m; blo = n / sqrt( m * 2 / 3 ); BLO = sqrt( n ); rep( i , 1 , n ) scanf("%d",A + i) , bl[i] = ( i - 1 ) / blo + 1 , a[i] = A[i]; sort( a + 1 , a + 1 + n ); int sz = unique( a + 1 , a + 1 + n ) - a - 1; rep( i , 1 , n ) A[i] = lower_bound( a + 1 , a + 1 + sz , A[i] ) - a; rep( i , 1 , m ) Q[i].rd( i ); sort( Q + 1 , Q + 1 + m , cmp ); rep( i , 1 , n ) Ls[i] = fwk::sum( n - A[i] ) , fwk::add( n - A[i] + 1 , 1 ); rep( i , 1 , n ) Ls[i] += Ls[i - 1]; mem( fwk::T ); per( i , n , 1 ) Rs[i] = fwk::sum( A[i] - 1 ) , fwk::add( A[i] , 1 ); per( i , n , 1 ) Rs[i] += Rs[i + 1]; int l = 1 , r = 0 , L , R , idx; rep( i , 1 , m ) { L = Q[i].l , R = Q[i].r , idx = Q[i].id; if( r < R ) Lqs[l - 1].eb( (dq){ r + 1 , R , idx , -1 } ) , ans[idx] += Ls[R] - Ls[r]; if( r > R ) Lqs[l - 1].eb( (dq){ R + 1 , r , idx , 1 } ) , ans[idx] -= Ls[r] - Ls[R]; r = R; if( l > L ) Rqs[R + 1].eb( (dq){ L , l - 1 , idx , -1 } ) , ans[idx] += Rs[L] - Rs[l]; if( l < L ) Rqs[R + 1].eb( (dq){ l , L - 1 , idx , 1 } ) , ans[idx] -= Rs[l] - Rs[L]; l = L; } long long re; rep( i , 1 , n ) { kuai1::add( A[i] - 1 ); for( auto& t : Lqs[i] ) { re = 0; rep( j , t.l , t.r ) re += kuai1::get( A[j] ); ans[t.id] += t.c * re; } } kuai2::tot = ( sz - 1 ) / BLO + 1; per( i , n , 1 ) { kuai2::add( A[i] + 1 ); for( auto& t : Rqs[i] ) { re = 0; rep( j , t.l , t.r ) re += kuai2::get( A[j] ); ans[t.id] += t.c * re; } } rep( i , 1 , m ) ans[Q[i].id] += ans[Q[i - 1].id]; rep( i , 1 , m ) printf("%lld\n",ans[i]); }
signed main() {
solve(); }
|