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]

? 2025. All Rights Reserved. 滬ICP備2023009024號-1