USACO20OPEN Haircut G
阿新 • • 發佈:2020-12-01
Solution
不會做,於是參考題解
假設現在 \(\mathrm{John}\) 不再需要為肆意生長的頭髮而煩惱了,而是成為了一個因禿頭而抓狂的脫髮人士。現在,我們把理髮看成是生髮,那麼第 \(i\) 根頭髮的極限長度就是 \(a_i\).
頭髮從 \(0\) 開始生長,在到達極限長度之前,每秒生長 \(1\) 個單位長度。現在我們把題目中的 \(j\) 看成是時間,那麼第 \(j\) 秒頭髮最長一定不會超過 \(j\). 這不是正好符合題目限制嗎?
顯而易見的,第 \(0\) 秒的逆序對個數是 \(0\). 那麼,我們現在需要考慮的是第 \(j\) 秒新增的逆序對。
Code
#include <iostream> #include <cstdio> #include <cstring> #define LL long long #define lowbit(x) (x & (-x)) using namespace std; const int N = 2333333; LL n, a[N], sum[N], t[N]; void add(LL x) { while(x <= n + 1) t[x]++, x += lowbit(x); } LL query(LL x) { LL res = 0; while(x) res += t[x], x -= lowbit(x); return res; } int main() { scanf("%lld", &n); memset(t, 0, sizeof(t)); memset(sum, 0, sizeof(sum)); for(int i = 1; i <= n; i++) { scanf("%lld", &a[i]), a[i]++; sum[a[i] + 1] += query(n + 1) - query(a[i]); add(a[i]); } for(int i = 1; i <= n; i++) { sum[i] += sum[i - 1]; printf("%lld\n", sum[i]); } return 0; }