#include "message.h" #include "teatr.h" #include "bits/stdc++.h" using namespace std; using ll = long long; using Vi = vector<int>; using Pii = pair<int,int>; #define x first #define y second #define pb push_back #define mp make_pair #define rep(i,b,e) for(int i=(b); i<(e); i++) #define each(a,x) for(auto& a : (x)) #define all(x) (x).begin(),(x).end() #define sz(x) int((x).size()) #define endl "\n" const long long inf = 2e17 + 10; const int big = 1e6; const int maxK = 1e6; struct tree{ int base = 1; vector<int>sum; void init( int n ){ while( base < n+2 ){ base *= 2; } sum.resize(2*base,0); } void insert( int a, int c ){ a += base; while( a >= 1 ){ sum[a] += c; a /= 2; } } int query( int a, int b ){ a += base - 1; b += base + 1; int res = 0; while( a/2 != b/2 ){ if( a%2 == 0 ) res += sum[a+1]; if( b%2 == 1 ) res += sum[b-1]; a /= 2; b /= 2; } return res; } }; long long solve_interval( int beg, int end ){ tree T; T.init( maxK+1 ); long long res = 0; for( int i = beg; i <= end; i++ ){ res += T.query( GetElement(i)+1, maxK+1 ); //cout << GetElement(i) << " "; T.insert( GetElement(i), 1 ); } //cout << endl; return res; } long long merge( int beg1, int end1, int beg2, int end2 ){ vector<int>V; V.resize(maxK+1,0); for( int i = beg1; i <= end1; i++ ){ V[ GetElement(i) ]++; } for( int i = maxK; i >= 1; i-- ){ V[i] += V[i+1]; } long long res = 0; for( int i = beg2; i <= end2; i++ ){ res += V[ GetElement(i) + 1 ]; } return res; } void count(){ int procId = MyNodeId(); int n = GetN(); int beg[32], end[32]; for( int i = 0; i < 16; i++ ){ beg[i+16] = n*i/16; end[i+16] = n*(i+1)/16 - 1; } for( int i = 15; i >= 1; i-- ){ beg[i] = beg[2*i]; end[i] = end[2*i+1]; } if( procId >= 16 ){ long long x = solve_interval( beg[procId], end[procId] ); PutLL(0,x); Send(0); }else { long long x = merge( beg[2*procId], end[2*procId], beg[2*procId+1], end[2*procId+1] ); PutLL(0,x); Send(0); } } void answer(){ long long res = 0; for( int i = 1 ; i < 32; i++ ){ Receive(i); res += GetLL(i); } cout << res << endl; } int main(){ int numberOfProc = NumberOfNodes(); int procId = MyNodeId(); int n = GetN(); if( n < big ){ if( procId == 0 ){ cout << solve_interval(0,n-1) << endl; } return 0; } if( procId > 31 ){ return 0; } if( procId == 0 ){ answer(); }else { count(); } }
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 | #include "message.h" #include "teatr.h" #include "bits/stdc++.h" using namespace std; using ll = long long; using Vi = vector<int>; using Pii = pair<int,int>; #define x first #define y second #define pb push_back #define mp make_pair #define rep(i,b,e) for(int i=(b); i<(e); i++) #define each(a,x) for(auto& a : (x)) #define all(x) (x).begin(),(x).end() #define sz(x) int((x).size()) #define endl "\n" const long long inf = 2e17 + 10; const int big = 1e6; const int maxK = 1e6; struct tree{ int base = 1; vector<int>sum; void init( int n ){ while( base < n+2 ){ base *= 2; } sum.resize(2*base,0); } void insert( int a, int c ){ a += base; while( a >= 1 ){ sum[a] += c; a /= 2; } } int query( int a, int b ){ a += base - 1; b += base + 1; int res = 0; while( a/2 != b/2 ){ if( a%2 == 0 ) res += sum[a+1]; if( b%2 == 1 ) res += sum[b-1]; a /= 2; b /= 2; } return res; } }; long long solve_interval( int beg, int end ){ tree T; T.init( maxK+1 ); long long res = 0; for( int i = beg; i <= end; i++ ){ res += T.query( GetElement(i)+1, maxK+1 ); //cout << GetElement(i) << " "; T.insert( GetElement(i), 1 ); } //cout << endl; return res; } long long merge( int beg1, int end1, int beg2, int end2 ){ vector<int>V; V.resize(maxK+1,0); for( int i = beg1; i <= end1; i++ ){ V[ GetElement(i) ]++; } for( int i = maxK; i >= 1; i-- ){ V[i] += V[i+1]; } long long res = 0; for( int i = beg2; i <= end2; i++ ){ res += V[ GetElement(i) + 1 ]; } return res; } void count(){ int procId = MyNodeId(); int n = GetN(); int beg[32], end[32]; for( int i = 0; i < 16; i++ ){ beg[i+16] = n*i/16; end[i+16] = n*(i+1)/16 - 1; } for( int i = 15; i >= 1; i-- ){ beg[i] = beg[2*i]; end[i] = end[2*i+1]; } if( procId >= 16 ){ long long x = solve_interval( beg[procId], end[procId] ); PutLL(0,x); Send(0); }else { long long x = merge( beg[2*procId], end[2*procId], beg[2*procId+1], end[2*procId+1] ); PutLL(0,x); Send(0); } } void answer(){ long long res = 0; for( int i = 1 ; i < 32; i++ ){ Receive(i); res += GetLL(i); } cout << res << endl; } int main(){ int numberOfProc = NumberOfNodes(); int procId = MyNodeId(); int n = GetN(); if( n < big ){ if( procId == 0 ){ cout << solve_interval(0,n-1) << endl; } return 0; } if( procId > 31 ){ return 0; } if( procId == 0 ){ answer(); }else { count(); } } |