题目链接:Eades
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <vector>
#include <algorithm>
using namespace std ;
typedef long long LL ;
typedef pair < int , int > pii ;
#define clr( a , x ) memset ( a , x , sizeof a )
#define root 1 , 1 , n
#define ls ( o << 1 )
#define rs ( o << 1 | 1 )
#define lson ls , l , m
#define rson rs , m + 1 , r
const int MAXN = 300005 ;
const int INF = 2e9 + 9 ;
int pos[MAXN] ;
namespace FFT {
struct comp {
double r , i ;
comp () {}
comp ( double r , double i ) : r ( r ) , i ( i ) {}
comp operator + ( const comp& a ) const {
return comp ( r + a.r , i + a.i ) ;
}
comp operator - ( const comp& a ) const {
return comp ( r - a.r , i - a.i ) ;
}
comp operator * ( const comp& a ) const {
return comp ( r * a.r - i * a.i , r * a.i + i * a.r ) ;
}
comp conj () {
return comp ( r , -i ) ;
}
} A[MAXN] , B[MAXN] ;
const double pi = acos ( -1.0 ) ;
void FFT ( comp a[] , int n , int t ) {
for ( int i = 1 ; i < n ; ++ i ) {
if ( i < pos[i] ) swap ( a[i] , a[pos[i]] ) ;
}
for ( int d = 0 ; ( 1 << d ) < n ; ++ d ) {
int m = 1 << d , m2 = m << 1 ;
double o = pi * 2 / m2 * t ;
comp wn ( cos ( o ) , sin ( o ) ) ;
for ( int i = 0 ; i < n ; i += m2 ) {
comp w ( 1 , 0 ) ;
for ( int j = 0 ; j < m ; ++ j ) {
comp& A = a[i + j + m] ;
comp& B = a[i + j] ;
comp t = w * A ;
A = B - t ;
B = B + t ;
w = w * wn ;
}
}
}
if ( t == -1 ) {
for ( int i = 0 ; i < n ; ++ i ) {
a[i].r /= n ;
}
}
}
void mul ( LL *a , LL *b , LL *c , int k ) {
int i , j = __builtin_ctz ( k ) - 1 ;
for ( int i = 0 ; i < k ; ++ i ) {
pos[i] = pos[i >> 1] >> 1 | ( ( i & 1 ) << j ) ;
}
for ( int i = 0 ; i < k ; ++ i ) {
A[i] = comp ( a[i] , b[i] ) ;
}
FFT ( A , k , 1 ) ;
for ( int i = 0 ; i < k ; ++ i ) {
j = ( k - i ) & ( k - 1 ) ;
B[i] = ( A[i] * A[i] - ( A[j] * A[j] ).conj () ) * comp ( 0 , -0.25 ) ;
}
FFT ( B , k , -1 ) ;
for ( int i = 0 ; i < k ; ++ i ) {
c[i] = ( ( long long ) ( B[i].r + 0.5 ) ) ;
}
}
}
pii T[MAXN] ;
int val[MAXN] ;
vector < int > G[MAXN] ;
LL ans[MAXN] ;
LL A[MAXN] , B[MAXN] , C[MAXN] ;
int n , cur ;
void build ( int o , int l , int r ) {
if ( l == r ) {
scanf ( "%d" , &val[l] ) ;
T[o].first = val[l] ;
T[o].second = -l ;
return ;
}
int m = l + r >> 1 ;
build ( lson ) ;
build ( rson ) ;
T[o] = max ( T[ls] , T[rs] ) ;
}
pii query ( int L , int R , int o , int l , int r ) {
if ( L <= l && r <= R ) return T[o] ;
int m = l + r >> 1 ;
pii ans ( 0 , 0 ) ;
if ( L <= m ) ans = max ( ans , query ( L , R , lson ) ) ;
if ( m < R ) ans = max ( ans , query ( L , R , rson ) ) ;
return ans ;
}
void dfs ( int u , int L , int R ) {
if ( L + 1 > R - 1 ) return ;
if ( L + 1 == R - 1 ) {
ans[1] ++ ;
return ;
}
int x = L ;
int v = query ( L + 1 , R - 1 , root ).first ;
G[u].clear () ;
G[u].push_back ( x ) ;
while ( 1 ) {
if ( x + 1 > R - 1 ) break ;
int y = -query ( x + 1 , R - 1 , root ).second ;
if ( val[y] < v ) break ;
G[u].push_back ( y ) ;
x = y ;
}
G[u].push_back ( R ) ;
int t = G[u].size () - 1 ;
for ( int i = 0 ; i < t ; ++ i ) {
B[t - i - 1] = A[i] = G[u][i + 1] - G[u][i] ;
}
int nn = 1 ;
while ( nn < t ) nn <<= 1 ;
nn <<= 1 ;
for ( int i = t ; i < nn ; ++ i ) {
B[i] = A[i] = 0 ;
}
FFT::mul ( A , B , C , nn ) ;
for ( int i = 0 ; i < t - 1 ; ++ i ) {
ans[t - 1 - i] += C[i] ;
}
for ( int i = 1 ; i < G[u].size () ; ++ i ) {
++ cur ;
dfs ( cur , G[u][i - 1] , G[u][i] ) ;
}
}
void solve () {
scanf ( "%d" , &n ) ;
build ( root ) ;
cur = 1 ;
for ( int i = 1 ; i <= n ; ++ i ) {
ans[i] = 0 ;
}
dfs ( cur , 0 , n + 1 ) ;
LL res = 0 ;
for ( int i = 1 ; i <= n ; ++ i ) {
res += ans[i] ^ i ;
}
printf ( "%I64d\n" , res ) ;
}
int main () {
int T ;
scanf ( "%d" , &T ) ;
for ( int i = 1 ; i <= T ; ++ i ) {
solve () ;
}
return 0 ;
}