CodeTON Round 7 (Div. 1 + Div. 2, Rated, Prizes!)
树状数组+模拟(把所有情况讨论出来)(这是一个逆序问题,逆序问题的常见做法是cdq分治,但是我不知道这个题能不能写cdq,个人感觉用了一个类似于回溯的思想,当然这种基于某种顺序的思想是解决逆序问题的很好的方法),模拟过程下面有注释
# include <bits/stdc++.h>
using namespace std ;
using ll = int64_t ;
namespace predefine {
const long long inf = 0x3f3f3f3f3f3f3f3f ;
using Int = __int128 ;
using pll = pair < ll , ll > ;
# define IOS iostream::sync_with_stdio ( 0 ) ; cin.tie ( 0 ) ;
# define af( i , a , b ) for ( ll i = a ; i <= b ; ++ i )
# define df( i , a , b ) for ( ll i = a ; i >= b ; -- i )
# define Dg( x ) cout << " ------- " << x << " ------- " << '\n'
# define Dged Dg ( "Debug ed" )
# define Dgop Dg ( "Debug op" )
# define pr( x ) cout << #x << " = " << x << '\n'
# define pn putchar ('\n')
# define ps cout << "yes"
# define __fin( a ) freopen ( a , "r" , stdin )
# define __fout( a ) freopen ( a , "w+" , stdout )
# define lowbit( x ) ( x & ( - x ) )
}
using namespace predefine ;
//----- 板子 ---------------------------------------------------------------------------------------------------------
template < typename T >
struct Tree
{
using i64 = int64_t ;
i64 n ; vector < T > tree ;
explicit Tree ( i64 n ) : n ( n ) , tree ( vector < T > ( n + 1 ) ) {}
void add ( i64 u , i64 k ) { if ( u <= 0 ) return ;
while ( u <= n ) tree [ u ] += k , u += lowbit ( u ) ; }
i64 query ( i64 r ) { if ( r <= 0 ) return 0 ;
i64 cnt = 0 ;while ( r ) cnt += (i64) tree [ r ] , r -= lowbit ( r ) ;
return cnt ;}
};
//----- 板子 ---------------------------------------------------------------------------------------------------------
ll Pow ( ll a , ll b , ll mod ) {
a = a % mod ; ll ans = 1 ;
for ( ; b ; b >>= 1 ) { if ( b & 1 ) ans = ( a * ans ) % mod ; a = ( a * a ) % mod ; }
return ans ; }
inline ll sum1 ( ll _a ) { return ( _a * ( _a + 1 ) ) >> 1 ; }
inline ll sum2 ( ll _b ) { return _b * ( _b + 1 ) * ( 2 * _b + 1 ) / 6 ; }
ll dx [ 4 ] = { -1 , 0 , 1 , 0 } ;
ll dy [ 4 ] = { 0 , 1 , 0 , -1 } ;
// using ll = long long ;!!!
void solve () {
ll n , x ; cin >> n ;
vector < ll > v ( n + 1 ) ;
af ( i , 1 , n ) cin >> v [ i ] ;
Tree < ll > b ( n ) , c ( n ) , d ( n ) , e ( n ) ;
ll cnt = 0 ;
df ( i , n , 1 ) {
if ( v [ i ] != i ) {
++ cnt ;
d.add ( i , 1 ) ;
}
}
vector < ll > ans ( n + 1 ) ;
/*
推导过程
if v [ i ] > i
r:
( i ~ v [ i ] )
v [ j ] != j
-
( i < j < v [ j ] < v [ i ] )
if v [ i ] < i
r:
v [ i ] < v [ j ] < j < n
i < j
l:
( 0 ~ v [ i ] )
v [ j ] != j
-
( 0 < j < v [ j ] < v [ i ] < i )
*/
df ( i , n , 1 ) {
ll cntl = c.query ( v [ i ] ) ;
if ( v [ i ] > i ) {
ans [ v [ i ] ] = d.query ( v [ i ] ) - d.query ( i ) - cntl ;
c.add ( v [ i ] , 1 ) ;
}
if ( v [ i ] < i ) {
ans [ v [ i ] ] = b.query ( n ) - b.query ( v [ i ] ) ;
b.add ( v [ i ] , 1 ) ;
}
}
af ( i , 1 , n ) {
if ( v [ i ] < i ) {
ans [ v [ i ] ] += d.query ( v [ i ] ) - e.query ( v [ i ] ) ;
}
if ( i < v [ i ] ) {
e.add ( v [ i ] , 1 ) ;
}
}
af ( i , 1 , n ) {
cout << ans [ i ] << ' ' ;
}
cout << endl ;
}
int main () {
// __fin ( "in.in" ) ;
ll _ = 1 ;
// rd ( _ ) ;
cin >> _ ;
while ( _ -- ) {
solve () ;
}
return 0 ;
}
/*
//----- 数据 ---------------------------------------------------------------------------------------------------------
----------
*/