const int MAXN = 5100; #define lson l, m, rt << 1 #define rson m + 1, r, rt << 1 | 1 int tree[MAXN << 2]; void pushUP(int l, int r, int rt) { tree[rt] = (tree[rt << 1] + tree[rt << 1 | 1]); } void build(int l, int r, int rt) { if (l == r) { tree[rt] = 0; return; } int m = (l + r) >> 1; build(lson); build(rson); pushUP(l, r, rt); } void update(int p, int add, int l, int r, int rt) { if (l == r) { tree[rt] += add; return; } int m = (l + r) >> 1; if (p <= m) update(p, add, lson); else update(p, add, rson); pushUP(l, r, rt); } int query(int L, int R, int l, int r, int rt) { if (L <= l && r <= R) return tree[rt]; int ret = 0, m = (l + r) >> 1; if (L <= m) ret += query(L, R, lson); if (R > m) ret += query(L, R, rson); return ret; } int ipt[MAXN]; int main() { // freopen("in.txt", "r", stdin); int num; while (~RI(num)) { build(0, num, 1); REP(i, num) { RI(ipt[i]); } int t = 0, ans = INF, l = 0, r = -1; REP(i, 2 * num - 1) { if (r - l + 1 == num) { ans = min(ans, t); if (ipt[l] >= 1) t -= query(0, ipt[l] - 1, 0, num - 1, 1); update(ipt[l], -1, 0, num - 1, 1); l++; } if (ipt[i % num] <= num - 1) t += query(ipt[i % num], num - 1, 0, num - 1, 1); update(ipt[i % num], 1, 0, num - 1, 1); r++; } WI(ans); } return 0; }
实际上考虑一下当num个数都插入到线段树中时,这时候删除的数都处于序列的一段。那么就没必要每次都在进行线段树操作了,知道端点的值而且树种的值是0-num的树,那么对于0到ipt[i] - 1之间的数都是减少的逆序数;对于ipt[i] + 1到num - 1的数每一个都加一。
const int MAXN = 5100; #define lson l, m, rt << 1 #define rson m + 1, r, rt << 1 | 1 int tree[MAXN << 2]; void pushUP(int l, int r, int rt) { tree[rt] = (tree[rt << 1] + tree[rt << 1 | 1]); } void build(int l, int r, int rt) { if (l == r) { tree[rt] = 0; return; } int m = (l + r) >> 1; build(lson); build(rson); pushUP(l, r, rt); } void update(int p, int add, int l, int r, int rt) { if (l == r) { tree[rt] += add; return; } int m = (l + r) >> 1; if (p <= m) update(p, add, lson); else update(p, add, rson); pushUP(l, r, rt); } int query(int L, int R, int l, int r, int rt) { if (L <= l && r <= R) return tree[rt]; int ret = 0, m = (l + r) >> 1; if (L <= m) ret += query(L, R, lson); if (R > m) ret += query(L, R, rson); return ret; } int ipt[MAXN]; int main() { // freopen("in.txt", "r", stdin); int num; while (~RI(num)) { build(0, num, 1); REP(i, num) { RI(ipt[i]); } int ans = 0, l = 0, r = -1, Min = INF; REP(i, num) { if (ipt[i] <= num - 1) ans += query(ipt[i], num - 1, 0, num - 1, 1); update(ipt[i], 1, 0, num - 1, 1); } Min = min(Min, ans); REP(i, num - 1) { ans += -2 * ipt[i] + num - 1; Min = min(Min, ans); } WI(Min); } return 0; }
原文:http://blog.csdn.net/wty__/article/details/21187001