Tired of his stubborn cowlick, Farmer John decides to get a haircut. He has NN (1≤N≤1051≤N≤105) strands of hair arranged in a line, and strand ii is initially AiAi micrometers long (0≤Ai≤N0≤Ai≤N). Ideally, he wants his hair to be monotonically increasing in length, so he defines the "badness" of his hair as the number of inversions: pairs (i,j)(i,j) such that i<ji<j and Ai>AjAi>Aj.
For each of j=0,1,…,N−1j=0,1,…,N−1, FJ would like to know the badness of his hair if all strands with length greater than jj are decreased to length exactly jj.
(Fun fact: the average human head does indeed have about 105105 hairs!)
The first line contains NN.The second line contains A1,A2,…,AN.A1,A2,…,AN.
For each of j=0,1,…,N−1j=0,1,…,N−1, output the badness of FJ's hair on a new line.Note that the large size of integers involved in this problem may require the use of 64-bit integer data types (e.g., a "long long" in C/C++).
5 5 2 3 3 0
0 4 4 5 7
The fourth line of output describes the number of inversions when FJ's hairs are decreased to length 3. Then A=[3,2,3,3,0]A=[3,2,3,3,0] has five inversions: A1>A2,A1>A5,A2>A5,A3>A5,A1>A2,A1>A5,A2>A5,A3>A5, and A4>A5A4>A5.
Problem credits: Dhruv Rohatgi
[/hide]
(Analysis by Benjamin Qi)
For each 0≤j<N0≤j<N we need to count the number of pairs (x,y)(x,y) such that x<yx<y, A[x]>A[y]A[x]>A[y] and A[y]<jA[y]<j. It suffices to compute the number of x<yx<y such that A[x]>A[y]A[x]>A[y] for every yy; call this quantity n[y]n[y]. Then ans[j]=∑A[y]<jn[y]ans[j]=∑A[y]<jn[y] can be computed with prefix sums.
The value of n[y]n[y] for each yy can be found via the following process:
The collection can be a policy-based data structure in C++ or a binary indexed tree.
My code:
#include "bits/stdc++.h" using namespace std; void setIO(string s) { ios_base::sync_with_stdio(0); cin.tie(0); freopen((s+".in").c_str(),"r",stdin); freopen((s+".out").c_str(),"w",stdout); } #include <ext/pb_ds/tree_policy.hpp> #include <ext/pb_ds/assoc_container.hpp> using namespace __gnu_pbds; template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; const int MX = 1e5+5; int N; long long numInv[MX]; vector<int> todo[MX]; int main() { setIO("haircut"); int N; cin >> N; vector<int> A(N); for (int& t: A) cin >> t; for (int i = 0; i < N; ++i) todo[A[i]].push_back(i); Tree<int> T; for (int i = N; i >= 0; --i) { for (int t: todo[i]) numInv[i+1] += T.order_of_key(t); for (int t: todo[i]) T.insert(t); } for (int i = 1; i < N; ++i) numInv[i] += numInv[i-1]; for (int i = 0; i < N; ++i) cout << numInv[i] << "\n"; }
Dhruv Rohatgi's code:
#include <iostream> #include <algorithm> using namespace std; #define MAXN 100005 int N; int A[100000]; int T[MAXN+1]; int getSum(int i) { int c=0; for(++i; i > 0 ; i -= (i & -i)) c += T[i]; return c; } void set(int i,int dif) { for(++i; i < MAXN ; i += (i & -i)) T[i] += dif; } long long cnt[100000]; int main() { freopen("haircut.in","r",stdin); freopen("haircut.out","w",stdout); cin >> N; int a; for(int i=0;i<N;i++) { cin >> a; a++; cnt[a] += i - getSum(a); set(a, 1); } long long ans = 0; for(int j=1;j<=N;j++) { cout << ans << '\n'; ans += cnt[j]; } }
[/hide]
翰林课程体验,退费流程快速投诉邮箱: yuxi@linstitute.net 沪ICP备2023009024号-1