---
# System prepended metadata

title: 分治
tags: [algorithm]

---

---
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';
	}
}
```
