QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#111728 | #3238. Just So You Know | Sorting | 0 | 0ms | 0kb | C++20 | 4.7kb | 2023-06-08 01:09:28 | 2023-06-08 01:09:31 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
typedef unsigned long long ull ;
typedef pair < int , int > pii ;
typedef vector < int > vi ;
#define fi first
#define se second
mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
const int MAXN = 1e6 + 7 ;
int n ;
int ori[ MAXN ] ;
int x[ MAXN ] , y[ MAXN ] , sws[ MAXN ] , srank[ MAXN ] ;
int sa[ MAXN ] , lcp[ MAXN ] ;
void SuffixArray(int lim=256) { // or basic_string<int>
int k = 0, a, b;
int len = n + 1 ;
for ( int i = 0 ; i < len ; ++ i ) {
sa[ i ] = i ; lcp[ i ] = 0 ;
}
x[ len - 1 ] = 0 ;
// vi x(all(s)+1), y(n), ws(max(n, lim)), rank(n);
// sa = lcp = y, iota(all(sa), 0);
for (int j = 0, p = 0; p < len; j = max(1, j * 2), lim = p) {
p = j;
for ( int i = 0 ; i < len ; ++ i ) { y[ i ] = len - j + i ; }
rep(i,0,len) if (sa[i] >= j) y[p++] = sa[i] - j;
// fill(all(ws), 0);
for ( int i = 0 ; i < max ( len , lim ) ; ++ i ) {
sws[ i ] = 0 ;
}
rep(i,0,len) sws[x[i]]++;
rep(i,1,lim) sws[i] += sws[i - 1];
for (int i = len; i--;) sa[--sws[x[y[i]]]] = y[i];
swap(x, y), p = 1, x[sa[0]] = 0;
rep(i,1,len) a = sa[i - 1], b = sa[i], x[b] =
(y[a] == y[b] && y[a + j] == y[b + j]) ? p - 1 : p++;
}
rep(i,1,len) srank[sa[i]] = i;
for (int i = 0, j; i < len - 1; lcp[srank[i++]] = k)
for (k && k--, j = sa[srank[i] - 1];
ori[i + k] == ori[j + k]; k++);
}
ll freq[ MAXN ] ;
int prv[ MAXN ] , rnk[ MAXN ] , sz[ MAXN ] , lstmod[ MAXN ] ;
vector < int > at_val[ MAXN ] ;
inline int get ( int x ) {
while ( prv[ x ] != x ) {
x = prv[ x ] = prv[ prv[ x ] ] ;
}
return x ;
}
int ens[ MAXN ] ;
void solve ( ) {
cin >> n ;
// n = MAXN - 7 ;
for ( int i = 0 ; i <= n ; ++ i ) {
freq[ i ] = 0 ;
prv[ i ] = i , rnk[ i ] = 0 , sz[ i ] = 1 ;
at_val[ i ].clear ( ) ;
}
for ( int i = 0 ; i < n ; ++ i ) {
cin >> x[ i ] ;
++ x[ i ] ;
ori[ i ] = x[ i ] ;
// x = rand ( ) % 100 + 1 ;
}
SuffixArray ( 102 ) ;
for ( int i = 1 ; i <= n ; ++ i ) {
at_val[ lcp[ i ] ].push_back ( i ) ;
lstmod[ i ] = n - sa[ i ] ;
}
for ( int ctr = n ; ctr >= 0 ; -- ctr ) {
for ( auto x : at_val[ ctr ] ) {
int rt1 = get ( x ) ;
freq[ sz[ rt1 ] ] += lstmod[ rt1 ] - ctr ;
lstmod[ rt1 ] = ctr ;
if ( x > 0 ) {
int rt2 = get ( x - 1 ) ;
freq[ sz[ rt2 ] ] += lstmod[ rt2 ] - ctr ;
lstmod[ rt2 ] = ctr ;
if ( rnk[ rt1 ] < rnk[ rt2 ] ) { swap ( rt1 , rt2 ) ; }
rnk[ rt1 ] += ( rnk[ rt1 ] == rnk[ rt2 ] ) ;
prv[ rt2 ] = rt1 ;
sz[ rt1 ] += sz[ rt2 ] ;
}
}
}
/**
for ( int i = 1 ; i <= n ; ++ i ) {
printf ( "%d " , freq[ i ] ) ;
}
printf ( "\n" ) ;
**/
ll up = 0 , down = 1LL * n * ( n + 1 ) / 2 ;
int rem = -1 ;
int stpos = 1 , tot = 0 ;
auto proc = [ & ] ( int x , int y , ll cnt ) {
up += cnt * ( x + y ) ;
freq[ x ] -= cnt , freq[ y ] -= cnt ;
if ( x + y <= n ) {
freq[ x + y ] += cnt ;
}
else {
while ( cnt > 0 ) {
-- cnt ;
ens[ ++ tot ] = x + y ;
}
}
};
for ( int i = 1 ; i <= n ; ++ i ) {
if ( freq[ i ] == 0 ) { continue ; }
if ( rem != -1 ) {
up += rem + i ;
-- freq[ rem ] , -- freq[ i ] ;
if ( rem + i <= n ) { ++ freq[ rem + i ] ; }
else { ens[ ++ tot ] = rem + i ; }
rem = -1 ;
}
ll cnt = freq[ i ] / 2 ;
up += cnt * 2 * i ;
freq[ i ] -= 2 * cnt ;
if ( 2 * i <= n ) { freq[ 2 * i ] += cnt ; }
else {
while ( cnt > 0 ) {
-- cnt ;
ens[ ++ tot ] = 2 * i ;
}
}
if ( freq[ i ] > 0 ) { rem = i ; }
}
if ( rem != -1 ) {
ens[ 0 ] = rem ;
-- stpos ;
}
while ( stpos + 1 <= tot ) {
ll x = ens[ stpos ] , y = ens[ stpos + 1 ] ;
stpos += 2 ;
up += x + y ;
ens[ ++ tot ] = x + y ;
}
ll hh = __gcd ( up , down ) ;
up /= hh , down /= hh ;
if ( down == 1 ) { cout << up << "\n" ; }
else { cout << up << "/" << down << "\n" ; }
}
int main ( ) {
ios_base :: sync_with_stdio ( false ) ;
cin.tie ( NULL ) ;
int t = 1 ; cin >> t ;
while ( t -- ) { solve ( ) ; }
return 0 ;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Time Limit Exceeded
input:
1000 1033 25 82 89 85 87 49 93 78 46 30 16 55 39 50 47 99 88 31 80 70 27 85 5 2 65 40 87 6 18 34 42 68 61 73 68 36 47 8 28 83 88 19 13 27 89 64 67 26 65 35 55 50 41 5 96 54 47 82 15 85 97 62 61 36 20 49 35 9 51 89 49 91 59 12 40 63 27 39 56 49 92 45 79 34 37 78 1 2 23 53 15 0 14 13 42 30 53 80 80 79...