1. 程式人生 > 其它 >Codeforces Round #723 (Div. 2) D. Kill Anton(樹狀陣列)

Codeforces Round #723 (Div. 2) D. Kill Anton(樹狀陣列)

目錄

Description

給出一個字串 s,每次可以交換兩個相鄰的字元,要構造一個合法的字串 t,使得 t 變為 s 所需要的操作次數最多

Input

4 
ANTON 
NAAN 
AAAAAA 
OAANTTON

Output

NNOTA 
AANN 
AAAAAA 
TNNTAOOA 

Solution

前置結論,操作次數最多的時候一定是相同的字母連線在一起的時候,比如: AAANNNOOTTT
至於結論的正確性,我想這應該是逆序對的特性;
有了結論之後,接下來只要列舉 ANOT,ANTO....等 24 種組合找到逆序對最多的字串就可以了;

Code

const int N = 1e5 + 5;

    ll n, m, _;
    int i, j, k;
    int a[N];
    string t = "ANOT";
    int bit[4];
    int c[N], b[N];
    map<char, vector<int>> mp;

void clear()
{
    mp.clear();
    bit[0] = bit[1] = bit[2] = bit[3] =0;
    rep(i, 0, n) c[i] = 0;
    t = "ANOT";
}

void add(int x)
{
    for(; x <= n; x += lowbit(x)){
        c[x] ++;
    }
}

int ask(int x)
{
    int ans = 0;
    for(; x; x -= lowbit(x)){
        ans += c[x];
    }
    return ans;
}

int idx(char ch)
{
    if(ch == 'A') return 0;
    if(ch == 'N') return 1;
    if(ch == 'O') return 2;
    if(ch == 'T') return 3;
}

string work(string s)
{
    string ans = "";
    rep(i, 0, 3){
        int x = idx(t[i]);
        rep(j, 1, bit[x]) ans += t[i];
    }
    return ans;
}

void init(string s)
{
    for(int i = 0; s[i]; i ++){
        mp[s[i]].pb(i + 1);
    }
    rep(i, 0, n) c[i] = 0;
}

ll go(string s)
{
    int sz = s.size();
    for(int i = sz - 1; i >= 0; i--){
        b[i + 1] = *mp[s[i]].rbegin();
        mp[s[i]].pop_back();
        //dbg(b[i + 1]);
    }
    ll ans = 0;
    per(i, 1, sz){
        ans += ask(b[i]);
        add(b[i]);
    }
    return ans;
}

signed main()
{
    IOS;
    rush(){
        string str, s, ans;
        cin >> str;
        n = str.size();
        for(int i = 0; str[i]; i++){
            int x = idx(str[i]);
            bit[x] ++;
        }
        ll maxx = 0;
        do{
            init(str);
            s = work(str);
            ll tmp = go(s);
            if(tmp >= maxx){
                maxx = tmp;
                ans = s;
            }
        }while(next_permutation(t.begin(), t.end()));
        ps(ans.c_str());
        clear();
    }
    return 0;
}