1. 程式人生 > >題目1:有一個數的出現次數嚴格大於n/2;題目2:逆序對個數

題目1:有一個數的出現次數嚴格大於n/2;題目2:逆序對個數

HHHHHHHHH

    下面為方法四的程式碼

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
int a[maxn], t[maxn];
long long cnt;
//oid prt(int n) {
// for(int i = 1; i <= n; i++) printf("%d ", a[i]);
// printf("\n");
//}
void solve(int l, int r) {

if(l >= r) return;

int mid = (l + r) >> 1;

solve(l, mid);//分治左邊

solve(mid + 1, r);//分治右邊 // printf("solve(%d, %d)\n", l, r); // prt(5);// printf("cnt=%d\n", cnt);

//分治過程中已經排好序,用兩個指標掃描一遍兩邊

for(int i = mid, j = r; i >= l; i--) {

while(a[i] <= a[j] && j > mid) j--;

if(j - mid == 0) break;

cnt += j - mid;

}// printf("cnt=%d\n", cnt);

//排序,類似歸併排序,兩個指標掃描兩邊

for(int i = l; i <= mid; i++) t[i] = a[i];//複製

for(int i = l, j = mid + 1; ; ) {

if(t[i] > a[j]) a[i+j-mid-1] = a[j++];//把兩個指標較小的一個放到開始

else a[i+j-mid-1] = t[i++];

if(i > mid) break;

if(j > r) {

while(i <= mid) a[i+j-mid-1] = t[i++];

break;

}

}

}
int main() {

int T; scanf("%d", &T);

while(T--) {

int n; scanf("%d", &n);

for(int i = 1; i <= n; i++) scanf("%d", &a[i]);

cnt = 0;

solve(1, n);

printf("%lld\n", cnt);

}

return 0;

}