intmain(){ int t, n, cnt = 0; int a[1005]; int ret; scanf("%d", &t); while (t--) { cnt++; scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); ret = 0; for (int i = 0; i < n; i++) for (int j = i + 1; j < n; j++) if (a[i] > a[j]) ret++; printf("Scenario #%d:\n", cnt); printf("%d\n", ret); if (t) printf("\n"); } return0; }
运用树状数组
每次维护小于 K 的数的个数,从后往前求和,时间复杂度是 O(nlgn) 的,注意数的范围很大,是 2000000,这样用这种方法反而不快。
voidadd(int k){ while (k < MAX) { seg[k]++; k += k & -k; } }
intsum(int k){ int ret = 0; while (k) { ret += seg[k]; k -= k & -k; } return ret; }
intmain(){ int t, n, cnt = 0; int ret; scanf("%d", &t); while (t--) { cnt++; scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d", &a[i]); a[i] += 1000001; } ret = 0; memset(seg, 0, sizeof(seg)); for (int i = n - 1; i >= 0; i--) { ret += sum(a[i] - 1); add(a[i]); } printf("Scenario #%d:\n", cnt); printf("%d\n", ret); if (t) printf("\n"); } return0; }