QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#111715#3238. Just So You KnowSorting0 0ms0kbC++203.9kb2023-06-07 23:11:232023-06-07 23:11:24

Judging History

This is the latest submission verdict.

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-06-07 23:11:24]
  • Judged
  • Verdict: 0
  • Time: 0ms
  • Memory: 0kb
  • [2023-06-07 23:11:23]
  • Submitted

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()

struct SuffixArray {
	vi sa, lcp;
	SuffixArray(string& s, int lim=256) { // or basic_string<int>
		int n = sz(s) + 1, k = 0, a, b;
		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 < n; j = max(1, j * 2), lim = p) {
			p = j, iota(all(y), n - j);
			rep(i,0,n) if (sa[i] >= j) y[p++] = sa[i] - j;
			fill(all(ws), 0);
			rep(i,0,n) ws[x[i]]++;
			rep(i,1,lim) ws[i] += ws[i - 1];
			for (int i = n; i--;) sa[--ws[x[y[i]]]] = y[i];
			swap(x, y), p = 1, x[sa[0]] = 0;
			rep(i,1,n) 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,n) rank[sa[i]] = i;
		for (int i = 0, j; i < n - 1; lcp[rank[i++]] = k)
			for (k && k--, j = sa[rank[i] - 1];
					s[i + k] == s[j + k]; k++);
	}
};

const int MAXN = 1e6 + 7 ;

int n ;
string a ;

ll freq[ MAXN ] ;
int prv[ MAXN ] , rnk[ MAXN ] , sz[ MAXN ] , lstmod[ MAXN ] ;
pii srt[ MAXN ] ;
vector < int > at_val[ MAXN ] ;

int get ( int x ) {
    if ( prv[ x ] == -1 ) { return x ; }
    int y = get ( prv[ x ] ) ;
    prv[ x ] = y ;
    return y ;
}

void solve ( ) {
    cin >> n ;
    for ( int i = 0 ; i <= n ; ++ i ) {
        freq[ i ] = 0 ;
        prv[ i ] = -1 , rnk[ i ] = 0 , sz[ i ] = 1 ;
        at_val[ i ].clear ( ) ;
    }
    a.resize ( n ) ;
    for ( int i = 1 , x ; i <= n ; ++ i ) {
        cin >> x ;
        // x = rand ( ) % 100 + 1 ;
        a[ i - 1 ] = (char)x ;
    }
    auto aux = SuffixArray ( a ) ;
    for ( int i = 1 ; i <= n ; ++ i ) {
        at_val[ aux.lcp[ i ] ].push_back ( i ) ;
        lstmod[ i ] = n - aux.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 ;
    deque < ll > q ;
    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 ;
                q.push_back ( x + y ) ;
            }
        }
    };
    for ( int i = 1 ; i <= n ; ++ i ) {
        if ( freq[ i ] == 0 ) { continue ; }
        if ( rem != -1 ) { proc ( rem , i , 1 ) ; rem = -1 ; }
        proc ( i , i , freq[ i ] / 2 ) ;
        if ( freq[ i ] > 0 ) { rem = i ; }
    }
    if ( rem != -1 ) {
        q.push_front ( rem ) ;
    }
    while ( 1 ) {
        int x = q.front ( ) ; q.pop_front ( ) ;
        if ( q.empty ( ) == true ) { break ; }
        int y = q.front ( ) ; q.pop_front ( ) ;
        up += x + y ;
        q.push_back ( 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...

output:


result: