/ SeriousOJ /

Record Detail

Accepted


  
# Status Time Cost Memory Cost
#1 Accepted 41ms 45.426 MiB
#2 Accepted 176ms 45.91 MiB
#3 Accepted 111ms 45.75 MiB
#4 Accepted 151ms 45.789 MiB
#5 Accepted 178ms 45.891 MiB
#6 Accepted 213ms 46.344 MiB
#7 Accepted 305ms 50.176 MiB
#8 Accepted 309ms 50.25 MiB
#9 Accepted 314ms 50.25 MiB
#10 Accepted 317ms 50.254 MiB
#11 Accepted 310ms 50.164 MiB
#12 Accepted 318ms 50.254 MiB
#13 Accepted 86ms 54.332 MiB
#14 Accepted 209ms 54.539 MiB
#15 Accepted 210ms 54.535 MiB
#16 Accepted 196ms 54.535 MiB

Code

#include <bits/stdc++.h>
using namespace std;

#define SC               scanf
#define PF               printf
#define ull              unsigned long long
#define ld               long double
#define D                double
#define F                first
#define S                second
#define pb               push_back
#define sort_a(a)        sort(a.begin(),a.end());
#define sort_d(a)        sort(a.rbegin(),a.rend());
#define READ(f)          freopen(f, "r", stdin)
#define WRITE(f)         freopen(f, "w", stdout)
#define rev(s)           reverse(s.begin(),s.end())
#define __Heart__        ios_base::sync_with_stdio(false); cin.tie(NULL);
#define ll long long
typedef pair<int,int> PII;
const int MX = 1e5 + 5;
const int szAlph = 26;

int n, q, arr[MX], discovery_time[MX], finishing_time[MX], Time = 0;
char a[MX];
vector<int> Edge[MX];

int charToIndex(char c) {
    return c - 'a';
}

char indexToChar(int index) {
    return 'a' + index;
}

void DFS(int id, int par) {
    discovery_time[id] = ++Time;
    arr[Time] = charToIndex(a[id]);
    for (int child : Edge[id]) {
        if (child == par) continue;
        DFS(child, id);
    }
    finishing_time[id] = Time;
}

//void DFS(int id, int par) {
//    stack<pair<int, int>> st;
//    st.push({id, par});
//    vector<bool> is_vis (n + 1, false);
//
//    while (!st.empty()) {
//        auto it = st.top();
//
//        if (!is_vis[it.F]) {
//            is_vis[it.F] = true;
//            discovery_time[it.F] = ++Time;
//            arr[Time] = charToIndex(a[it.F]);
//            for (int child : Edge[it.F]) {
//                if (child != it.S) {
//                    st.push({child, it.F});
//                }
//            }
//        } else {
//            finishing_time[it.F] = Time;
//            st.pop();
//        }
//    }
//}

struct SegmentTreeNode {
    int maxFreq;
    int minValWithMaxFreq;
    int freqCount[szAlph];

    SegmentTreeNode() : maxFreq(0), minValWithMaxFreq(INT_MAX) {
        fill(freqCount, freqCount + szAlph, 0);
    }

    void merge(const SegmentTreeNode& left, const SegmentTreeNode& right) {
        maxFreq = 0;
        minValWithMaxFreq = INT_MAX;
        fill(freqCount, freqCount + szAlph, 0);

        for (int i = 0; i < szAlph; ++i) {
            freqCount[i] = left.freqCount[i] + right.freqCount[i];
            if (freqCount[i] > maxFreq) {
                maxFreq = freqCount[i];
                minValWithMaxFreq = i;
            } else if (freqCount[i] == maxFreq) {
                minValWithMaxFreq = min(minValWithMaxFreq, i);
            }
        }
    }
};

SegmentTreeNode tree[MX * 4];

void init(int node, int b, int e) {
    if (b == e) {
        tree[node].freqCount[arr[b]] = 1;
        tree[node].maxFreq = 1;
        tree[node].minValWithMaxFreq = arr[b];
        return;
    }
    int mid = (b + e) / 2;
    int left = node * 2;
    int right = node * 2 + 1;
    init(left, b, mid);
    init(right, mid + 1, e);
    tree[node].merge(tree[left], tree[right]);
}

SegmentTreeNode query(int node, int b, int e, int i, int j) {
    if (i > e || j < b) {
        return SegmentTreeNode();
    }
    if (b >= i && e <= j) {
        return tree[node];
    }
    int mid = (b + e) / 2;
    int left = node * 2;
    int right = node * 2 + 1;
    SegmentTreeNode leftResult = query(left, b, mid, i, j);
    SegmentTreeNode rightResult = query(right, mid + 1, e, i, j);

    SegmentTreeNode result;
    result.merge(leftResult, rightResult);
    return result;
}

void update(int node, int b, int e, int pos, int oldValue, int newValue) {
    if (pos > e || pos < b) return;

    if (b == e) {
        if (oldValue != newValue) {
            tree[node].freqCount[oldValue]--;
            if (tree[node].freqCount[oldValue] == 0) {
                tree[node].freqCount[oldValue] = 0;
            }
            tree[node].freqCount[newValue]++;
            tree[node].maxFreq = tree[node].freqCount[newValue];
            tree[node].minValWithMaxFreq = newValue;
        }
        return;
    }

    int mid = (b + e) / 2;
    int left = node * 2;
    int right = node * 2 + 1;

    if (pos <= mid) {
        update(left, b, mid, pos, oldValue, newValue);
    } else {
        update(right, mid + 1, e, pos, oldValue, newValue);
    }
    tree[node].merge(tree[left], tree[right]);
}

void solve() {
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];
    for (int i = 1; i < n; i++) {
        int u, v;
        cin >> u >> v;
        Edge[u].push_back(v);
        Edge[v].push_back(u);
    }

    DFS(1, -1);
    cin >> q;
    init(1, 1, n);

    for (int i = 0; i < q; i++) {
        int ty, node;
        cin >> ty >> node;
        int l = discovery_time[node];
        int r = finishing_time[node];
        if (ty == 1) {
            char newChar;
            cin >> newChar;
            int val = charToIndex(newChar);
            int oldValue = arr[l];
            update(1, 1, n, l, oldValue, val);
            arr[l] = val;
        } else {
            cout << indexToChar(query(1, 1, n, l, r).minValWithMaxFreq) << "\n";

        }
    }
}

int main() {
    __Heart__
    //READ("input15.txt");
     //WRITE("output15.txt") ;
    int t = 1; while (t--) solve();
}

Information

Submit By
Type
Submission
Problem
P1091 Alphabetical Kingdom
Language
C++17 (G++ 13.2.0)
Submit At
2024-10-03 14:26:09
Judged At
2024-11-11 02:51:27
Judged By
Score
100
Total Time
318ms
Peak Memory
54.539 MiB