QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#865418#9731. Fuzzy Rankingsurenjamts#RE 0ms3712kbC++204.5kb2025-01-21 18:12:542025-01-21 18:12:55

Judging History

This is the latest submission verdict.

  • [2025-01-21 18:12:55]
  • Judged
  • Verdict: RE
  • Time: 0ms
  • Memory: 3712kb
  • [2025-01-21 18:12:54]
  • Submitted

answer

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

using ll = long long;
using uint = unsigned int;
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define eb emplace_back
#define F first
#define S second
#define put(x) cout << (x) << '\n'
#define int long long
const int N = 2e5 + 5;
const int MOD = 998244353;

template <typename T, typename U>
ostream& operator<<(ostream& os, pair<T, U> p) {
    return os << "(" << p.first << ", " << p.second << ")";
}
template<typename T, typename U = char>
void print(const T &v, U end = ' ') {
    for (auto it : v) cout << it << end;
    cout << '\n';
}

void dfs1(int node, vector<vector<int>>& adj, vector<bool>& visited, stack<int>& finishOrder) {
    visited[node] = true;
    for (int neighbor : adj[node]) {
        if (!visited[neighbor]) {
            dfs1(neighbor, adj, visited, finishOrder);
        }
    }
    finishOrder.push(node); // Store nodes in finish order
}

void dfs2(int node, vector<vector<int>>& reverseAdj, vector<bool>& visited, vector<int>& component) {
    visited[node] = true;
    component.push_back(node);
    for (int neighbor : reverseAdj[node]) {
        if (!visited[neighbor]) {
            dfs2(neighbor, reverseAdj, visited, component);
        }
    }
}

vector<vector<int>> kosaraju(int n, vector<vector<int>>& edges) {

    vector<vector<int>> adj(n);
    for (auto& edge : edges) {
        adj[edge[0]].push_back(edge[1]);
    }

    // Step 2: Perform DFS on original graph to get finish times
    vector<bool> visited(n, false);
    stack<int> finishOrder;
    for (int i = 0; i < n; i++) {
        if (!visited[i]) {
            dfs1(i, adj, visited, finishOrder);
        }
    }

    // Step 3: Reverse the graph
    vector<vector<int>> reverseAdj(n);
    for (auto& edge : edges) {
        reverseAdj[edge[1]].push_back(edge[0]);
    }

    // Step 4: Perform DFS on reversed graph in decreasing order of finish times
    fill(visited.begin(), visited.end(), false);
    vector<vector<int>> stronglyConnectedComponents;
    while (!finishOrder.empty()) {
        int node = finishOrder.top();
        finishOrder.pop();
        if (!visited[node]) {
            vector<int> component;
            dfs2(node, reverseAdj, visited, component);
            stronglyConnectedComponents.push_back(component);
        }
    }

    return stronglyConnectedComponents;
}


void solve() {
    int n, k, q;
    cin >> n >> k >> q;
    vector<vector<int>> edges;
    vector<vector<int>> lists(k, vector<int>(n));
    for(auto &v : lists){
        for(int j = 0; j < n; j++){
            cin >> v[j];
            v[j]--;
            if(j > 0) edges.pb({v[j - 1], v[j]});
        }
    }

    for(auto edge : edges){
          //  put(make_pair(edge[0], edge[1]));
    }


    auto comps = kosaraju(n, edges);
    vector<int> compID(n);
    for(int i = 0; i < comps.size(); i++){
        for(int v : comps[i]) compID[v] = i + 1;
    }

    vector<vector<int>> p(k, vector<int>(n, 0));
    vector<vector<int>> ends(k);
    for(int i = 0; i < k; i++){
        int l = 0;
        int prev = lists[i][0], cur;
        ll sum = 0;
        for(int j = 1; j < n; j++){
            cur = lists[i][j];
            if(compID[cur] != compID[prev]){
               // put(make_pair(l, j));
                sum += (ll)(j - l) * (j - l - 1) / 2;
                p[i][j - 1] = sum;
                ends[i].pb(j - 1);
                l = j;
            }
            prev = cur;
        }
        sum += (ll)(n - l) * (n - l - 1) / 2;
        p[i][n - 1] = sum;
        ends[i].pb(n - 1);
     //   print(p[i]);
     //   print(ends[i]);
    }


    ll prev = 0;
    while(q--){
        ll id, l, r;
        cin >> id >> l >> r;
        id = (id + prev) % k;
        l = (l + prev) % n;
        r = (r + prev) % n;
        if(compID[l] == compID[r]){
            cout << (r - l + 1) * (r - l)/ 2 << '\n';
            prev = (r - l + 1) * (r - l)/ 2;
            continue;
        }
        ll ans = 0;

        ll L = *lower_bound(all(ends[id]), l);
        ll R = *(lower_bound(all(ends[id]), r) - 1);

        ans += (L - l + 1) * (L - l) / 2;
        ans += (r - R) * (r - R - 1) / 2;
        ans += p[id][R] - p[id][L];

     //   cout << L << ' ' << R << endl;
        put(ans);

        prev = ans;
    }
}

int32_t main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int test_cases;
    cin >> test_cases;
    while (test_cases--) {
        solve();
    }
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3712kb

input:

2
5 2 2
1 2 3 4 5
5 4 3 2 1
1 0 2
1 2 1
5 3 3
1 2 3 4 5
1 3 2 4 5
1 2 3 5 4
0 0 2
0 2 3
1 0 3

output:

3
10
1
1
2

result:

ok 5 lines

Test #2:

score: -100
Runtime Error

input:

2000
10 10 10
4 5 3 6 8 9 2 1 7 10
4 5 6 3 8 9 1 2 10 7
5 4 3 6 8 9 1 2 7 10
4 5 6 3 8 9 1 2 7 10
4 5 3 6 8 9 2 1 10 7
4 5 6 3 8 9 1 2 10 7
5 4 6 3 8 9 1 2 7 10
5 4 6 3 8 9 1 2 10 7
4 5 6 3 8 9 2 1 7 10
5 4 3 6 8 9 2 1 10 7
3 1 6
5 7 8
0 2 3
7 9 9
2 1 9
6 1 6
7 2 3
0 0 4
1 8 1
1 8 7
10 10 10
9 10 5 ...

output:


result: