E. Permutation Sorting codeforces CodeTON Round 7 (Div. 1 + Div. 2, Rated, Prizes!)

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 ;
}

/*
//-----  数据  ---------------------------------------------------------------------------------------------------------

----------
*/
  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值