---
tags: algorithm
---
# 分治
把大問題分成小問提
再從小問題合併上來
**必要條件**:你要確保合併是正確的
```graphviz
digraph {
"1~8" -> {"1~4", "5~8"}
"1~4" -> {"1~2", "3~4"}
"5~8" -> {"5~6", "7~8"}
"1~2" -> {"1", "2"}
"3~4" -> {"3", "4"}
"5~6" -> {"5", "6"}
"7~8" -> {"7", "8"}
}
```
## 分
```graphviz
digraph {
"[3, 7, 4, 6,2 ,5, 9, 1]"
"[3, 7, 4, 6,2 ,5, 9, 1]" -> {"[3, 7, 4, 6]", "[2 ,5, 9, 1]"}
"[3, 7, 4, 6]" -> {"[3, 7]", "[4, 6]"}
"[3, 7]" -> {"[3]", "[7]"}
"[4, 6]" -> {"[4]", "[6]"}
"[2 ,5, 9, 1]" -> {"[2, 5]", "[9, 1]"}
"[2, 5]" -> {"[2]", "[5]"}
"[9, 1]" -> {"[9]", "[1]"}
}
```
## 治
```graphviz
digraph{
{"[3]" "[7]"} -> "[3, 7]"
{"[4]" "[6]"} -> "[4, 6]"
{"[3, 7]", "[4, 6]"} -> "[3, 4, 6, 7]"
{"[2]", "[5]"} -> "[2, 5]"
{"[9]", "[1]"} -> "[1, 9]"
{"[2, 5]", "[1, 9]"} -> "[1, 2, 5, 9]"
{"[3, 4, 6, 7]","[1, 2, 5, 9]"} -> "[1, 2, 3, 4, 5, 6, 7, 9]"
}
```
# merge sort
```cpp=
#define inf int(2e9)
//#define inf 10000000000000000000000LL
void merge_sort(vector<int> &vc) {
if( vc.size() == 1 ) return;
const int sz = vc.size();
int m = sz>>1;
vector<int> vl( vc.begin(), vc.begin()+m ), vr( vc.begin()+m, vc.end() );
merge_sort( vl ); merge_sort( vr );
//merge( vl.begin(), vl.end(), vr.begin(), vr.end(), vc.begin() );
//v1 = vc[ 0~m-1 ]
int l_pos = 0, r_pos = 0, vc_pos = 0;
while( l_pos != int(vl.size()) && r_pos != int(vr.size()) ) {// vl.size()-1
if( vl[ l_pos ] > vr[ r_pos ] ) vc[ vc_pos ] = vr[ r_pos ], r_pos++;
else vc[ vc_pos ] = vl[ l_pos ], l_pos++;
vc_pos++;
}
while( l_pos != int( vl.size() )) vc[ vc_pos ] = vl[ l_pos ], vc_pos++, l_pos++;
while( r_pos != int( vr.size() )) vc[ vc_pos ] = vr[ r_pos ], vc_pos++, r_pos++;
return;
}
int main () {
int N; cin >> N;
//2^k ,
int sz = 1<<(__lg(N-1)+1); // 2 << __lg(vc.size()-1)
// 1<<q => 2^q
//vc.size() = 4, 1<<(1+1)
vector<int> vc(sz, inf);
for( int i = 0; i < N; i++ ) {
int a; cin >> a;
vc.emplace_back(a);
}
merge_sort(vc);
for( int i = 0; i < N; i++ ) cout << vc[i] << " \n"[i==N-1];
}
```
## [a132](https://dandanjudge.fdhs.tyc.edu.tw/ShowProblem?problemid=a132)
```cpp=
long long sum = 0LL;
void merge_sort( vector<int> &vc ) {
if( vc.size() == 1 ) return;
const int sz = vc.size();
int m = sz>>1; //sz/2
vector<int> vl( vc.begin(), vc.begin()+m ), vr( vc.begin()+m, vc.end() );
merge_sort( vl ); merge_sort( vr );
int l_pos = 0, r_pos = 0, vc_pos = 0;
while( l_pos != int( vl.size() ) && r_pos != int( vr.size() ) ) {
if( vl[ l_pos ] == vr[ r_pos ] ) {
sum += r_pos;
vc[ vc_pos ] = vl[ l_pos ];
l_pos++;
}
else if( vl[ l_pos ] > vr[ r_pos ] ) vc[ vc_pos ] = vr[ r_pos ], r_pos++;
else if( vl[ l_pos ] < vr[ r_pos ] ) {
sum += r_pos;
vc[ vc_pos ] = vl[ l_pos ];
l_pos++;
}
vc_pos++;
}
while( r_pos != int( vr.size() ) ) vc[ vc_pos ] = vr[ r_pos ], r_pos++, vc_pos++;
while( l_pos != int( vl.size() ) ) {
sum += r_pos;
vc[ vc_pos ] = vl[ l_pos ];
l_pos++;
vc_pos++;
}
return;
}
void solve() {
sum = 0LL;
int N; cin >> N;
vector<int> vc(N);
for( int i = 0; i < N; i++ ) cin >> vc[i]; // for(auot &i : vc) cin >> i;
merge_sort( vc );
cout << sum << '\n';
}
int main () {ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int T; cin >> T;
while( T-- ) solve();
}
```
## [a139](https://dandanjudge.fdhs.tyc.edu.tw/ShowProblem?problemid=a139)
```cpp=
struct point {
int x, y;
int org_pos, ans;
point() {};
point( int _x, int _y, int _org_pos ) : x(_x), y(_y), org_pos(_org_pos) {ans = 0;}
};
bool x_cmp( const point &a, const point &b ) {
return (a.x == b.x ? a.y > b.y : a.x < b.x );
}
bool pos_cmp( const point &a, const point &b) {
return a.org_pos < b.org_pos;
}
void merge_sort(vector<point> &vc) {
if( vc.size() == 1 ) return;
const int sz = vc.size();
int m = sz>>1;//sz/2
vector<point> vl( vc.begin(), vc.begin()+m), vr( vc.begin()+m, vc.end() );
merge_sort( vl ); merge_sort( vr );
int l_pos = 0, r_pos = 0, vc_pos = 0;
while( l_pos != int( vl.size() ) && r_pos != int( vr.size() ) ) {
if( vl[ l_pos ].y == vr[ r_pos ].y ) vc[ vc_pos ] = vr[ r_pos ], r_pos++;
else if( vl[ l_pos ].y > vr[ r_pos ].y ) vc[ vc_pos ] = vr[ r_pos ], r_pos++;
else {
//cout << "1: " << vl[ l_pos ].org_pos << " " << r_pos << ' ' << vr.size() << endl;
vl[ l_pos ].ans += int( vr.size() ) - r_pos;
vc[ vc_pos ] = vl[ l_pos ];
l_pos++;
}
vc_pos++;
}
while( r_pos != int( vr.size() ) ) vc[ vc_pos ] = vr[ r_pos ], r_pos++, vc_pos++;
while( l_pos != int( vl.size() ) ) {
//cout << "2: " << vl[ l_pos ].org_pos << " " << r_pos << ' ' << vr.size() << endl;
vl[ l_pos ].ans += int( vr.size() ) - r_pos;
vc[ vc_pos ] = vl[ l_pos ];
l_pos++;
vc_pos++;
}
/*
cout << "-----------------------\n";
for( auto &i : vc ) {
cout << i.x << ' ' << i.y << ' ' << i.org_pos << ' ' << i.ans << '\n';
}
cout << "----------------------\n";
*/
return;
}
void solve(int N) {
vector<point> vc(N);
for(int i = 0; i < N; i++) {
int x, y; cin >> x >> y;
vc[i] = point( x, y, i );
}
sort( vc.begin(), vc.end(), x_cmp);
/*
cout << "-----------------------\n";
for( auto &i : vc ) {
cout << i.x << ' ' << i.y << ' ' << i.org_pos << '\n';
}
cout << "----------------------\n";
*/
merge_sort(vc);
sort( vc.begin(), vc.end(), pos_cmp );
for( auto &i : vc ) {
cout << i.ans << '\n';
}
}
```