HDU 5497 Inversion

来源:互联网 发布:mac装win10连不上wifi 编辑:程序博客网 时间:2024/04/30 11:56

Problem Description
You have a sequence {a1,a2,...,an} and you can delete a contiguous subsequence of length m. So what is the minimum number of inversions after the deletion.
 

Input
There are multiple test cases. The first line of input contains an integerT, indicating the number of test cases. For each test case:

The first line contains two integers n,m(1n105,1m<n) - the length of the seuqence. The second line contains n integers a1,a2,...,an(1ain).

The sum of n in the test cases will not exceed 2×106.
 

Output
For each test case, output the minimum number of inversions.
 

Sample Input
23 11 2 34 24 1 3 2
 

Sample Output
01
 

Source
BestCoder Round #58 (div.2) 

利用两个树状数组维护一个前缀和一个后缀即可,开始写的两份代码写搓了各种TLE,无奈只好换种思路重写代码。

#include <cmath>#include <ctime>#include <cstdio>#include <cstdlib>#include <cstring>#include <cctype>#include <iostream>#include <string>#include <vector>#include <map>#include <algorithm>using namespace std;typedef long long ll;const int maxn = 100010;const ll inf  = (1LL<<50) + 10;struct Bit {    int n;    int tree[maxn];    void zero() {        memset(tree, 0, sizeof(tree));    }    inline int lowbit(int x) {        return x & (-x);    }    inline void update(int p, int c) {        for(int i = p; i <= n; i += lowbit(i)) {            tree[i] += c;        }        return ;    }    inline int getsum(int p) {        int ans = 0;        for(int i = p; i > 0; i -= lowbit(i)) {            ans += tree[i];        }        return ans;    }}bit1, bit2;inline int read() {    int c, x;    while(c = getchar(), !isdigit(c));    x = c - '0';    while(c = getchar(), isdigit(c)) x = x * 10 + c - '0';    return x;}int arr[maxn];int main() {    //freopen("aa.in", "r", stdin);    int T, n, m;    T = read();    while(T--) {        n = read();        m = read();        for(int i = 1; i <= n; ++i) {            arr[i] = read();        }        bit1.n = n; bit1.zero();        bit2.n = n; bit2.zero();        ll sum1 = 0, sum2 = 0, sum3 = 0;        for(int i = n; i > m; --i) {            sum2 += bit2.getsum(arr[i] - 1);            bit2.update(arr[i], 1);        }        ll ans = inf;        for(int i = 1; i + m - 1 <= n; ++i) {            ans = min(ans, sum1 + sum2 + sum3);            if(i + m <= n) {                sum3 -= (bit1.getsum(n) - bit1.getsum(arr[i+m]));                sum2 -= bit2.getsum(arr[i+m] - 1);                bit2.update(arr[i+m], -1);            }            sum3 += bit2.getsum(arr[i] - 1);            sum1 += (bit1.getsum(n) - bit1.getsum(arr[i]));            bit1.update(arr[i], 1);        }        printf("%I64d\n", ans);    }    return 0;}/*const int maxn = 100010;typedef long long ll;const ll inf = (1LL<<50) + 10;int arr[maxn];ll tree[maxn];int T, n, m;int lowbit(int x) {    return x & (-x);}void update(int x, int c) {    for(int i = x; i <= n; i += lowbit(i)) {        tree[i] += c;    }    return ;}ll getsum(int x) {    if(x == 0) return 0;    ll ans = 0;    for(int i = x; i > 0; i -= lowbit(i)) {        ans += tree[i];    }    return ans;}int dp1[maxn], dp2[maxn], dp3[maxn];int main() {    //freopen("aa.in", "r", stdin);    ll sum;    scanf("%d", &T);    while(T--) {        scanf("%d %d", &n, &m);        for(int i = 1; i <= n; ++i) {            scanf("%d", &arr[i]);        }        sum = 0;        memset(tree, 0, sizeof(tree));        memset(dp1, 0, sizeof(dp1));        for(int i = 1; i <= n; ++i) {            dp1[i] = dp1[i-1] + (getsum(n) - getsum(arr[i]));            update(arr[i], 1);        }        sum = dp1[n];        memset(tree, 0, sizeof(tree));        memset(dp2, 0, sizeof(dp2));        for(int i = n; i >= 1; --i) {            dp2[i] = dp2[i+1] + getsum(arr[i] - 1);            update(arr[i], 1);        }        memset(dp3, 0, sizeof(dp3));        memset(tree, 0, sizeof(tree));        for(int i = 1; i <= n; ++i) {            if(i <= m) {                dp3[i] = dp3[i-1] + (getsum(n) - getsum(arr[i]));                update(arr[i], 1);            } else {                update(arr[i-m], -1);                dp3[i] = dp3[i-1] - getsum(arr[i-m] - 1);                dp3[i] += (getsum(n) - getsum(arr[i]));                update(arr[i], 1);            }        }        ll ans = inf;        for(int i = m; i <= n; ++i) {            ll t = 0;            t += dp1[i] - dp1[i-m];            t += dp2[i-m+1] - dp2[i+1];            t -= dp3[i];            ans = min(ans, sum - t);        }        printf("%I64d\n", ans);    }    return 0;}*//*const int maxn = 100010;typedef long long ll;const ll inf = (1LL<<50) + 10;int arr[maxn];int tarr[maxn];ll tree[maxn];int T, n, m, tn;int lowbit(int x) {    return x & (-x);}void update(int x, int c) {    for(int i = x; i <= tn; i += lowbit(i)) {        tree[i] += c;    }    return ;}ll getsum(int x) {    ll ans = 0;    for(int i = x; i > 0; i -= lowbit(i)) {        ans += tree[i];    }    return ans;}inline int read() {    int c, x;    while(c = getchar(), !isdigit(c));    x = c - '0';    while(c = getchar(), isdigit(c)) x = x * 10 + c - '0';    return x;}int bsearch(int x) {    int l = 1, r = tn, mid;    while(l <= r) {        mid = (l + r) / 2;        if(tarr[mid] == x) {            return mid;        } else if(tarr[mid] < x) {            l = mid + 1;        } else {            r = mid - 1;        }    }    return -1;}int dp1[maxn], dp2[maxn], dp3[maxn];int main() {    //freopen("aa.in", "r", stdin);    ll sum;    T = read();    while(T--) {        n = read();        m = read();        for(int i = 1; i <= n; ++i) {            arr[i] = read();            tarr[i] = arr[i];        }        sort(tarr + 1, tarr + n + 1);        tn = unique(tarr + 1, tarr + n + 1) - tarr - 1;        for(int i = 1; i <= n; ++i) {            arr[i] = bsearch(arr[i]);        }        sum = 0;        memset(tree, 0, sizeof(tree));        memset(dp1, 0, sizeof(dp1));        for(int i = 1; i <= n; ++i) {            dp1[i] = dp1[i-1] + (getsum(tn) - getsum(arr[i]));            update(arr[i], 1);        }        sum = dp1[n];        memset(tree, 0, sizeof(tree));        memset(dp2, 0, sizeof(dp2));        for(int i = n; i >= 1; --i) {            dp2[i] = dp2[i+1] + getsum(arr[i] - 1);            update(arr[i], 1);        }        memset(dp3, 0, sizeof(dp3));        memset(tree, 0, sizeof(tree));        for(int i = 1; i <= n; ++i) {            if(i <= m) {                dp3[i] = dp3[i-1] + (getsum(tn) - getsum(arr[i]));                update(arr[i], 1);            } else {                update(arr[i-m], -1);                dp3[i] = dp3[i-1] - getsum(arr[i-m] - 1);                dp3[i] += (getsum(tn) - getsum(arr[i]));                update(arr[i], 1);            }        }        ll ans = inf;        for(int i = m; i <= n; ++i) {            ll t = 0;            t += dp1[i] - dp1[i-m];            t += dp2[i-m+1] - dp2[i+1];            t -= dp3[i];            ans = min(ans, sum - t);        }        printf("%I64d\n", ans);    }    return 0;}*/


0 0
原创粉丝点击