QOJ.ac

QOJ

Type: Editorial

Status: Open

Posted by: ILearnedSomeCoding

Posted at: 2026-03-01 09:18:48

Last updated: 2026-03-01 21:12:50

Back to Problem

题!解!

我们把图中的pattern称作“模式”。
模式长度是 n,用 0-based 下标 i = 0 到 n - 1 表示第 i + 1 拍。第 i 拍会在 i + a_i 拍回到手中。我们记 f(i) = (i + a_i) % n。
我们可以发现,f 函数会形成很多循环。循环内里面的球只会在循环里(废话文学),所以只要统计每个循环里面哪个球会在哪个手。
如果 a_i 不全为偶数,那么那一定会换手了。
假如 n 是偶数,那么一个 i 是一定在一个手扔的。那么直接判断 i 奇偶。
n 是奇数的话答案应该根据有几次循环数量来看加多少。

// ILearnedSomeCoding 的万能头1.1
#include<iostream>
#include<vector>
#define code using
#define by namespace
#define ILearnedSomeCoding std
code by ILearnedSomeCoding;
#define ll long long
#define int64 long long
#define ull unsigned long long
#define uint64 unsigned long long
#define int128 __int128
#define uint128 __uint128_t
#define PQ priority_queue
#define fir(_S, _E, _T) for(int i = _S;i <= _E;i += _T)
#define fjr(_S, _E, _T) for(int j = _S;j <= _E;j += _T)
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t; 
    // cin >> t;
    while(t--){
        int n; 
        cin >> n;
        vector<ll> a(n);
        fir(0, n - 1, 1) cin >> a[i];
        vector<int> f(n);
        fir(0, n - 1, 1){
            f[i] = ((i + (a[i] % n)) % n);
        }
        vector<char> vis(n, 0);
        ll only1 = 0, only2 = 0, both = 0;

        fir(0, n - 1, 1){
            if(vis[i]) continue;

            int u = i;
            ll C = 0;
            bool all_even = 1;
            while(!vis[u]){
                vis[u] = 1;
                if(a[u] & 1) all_even = 0;
                C += ((ll)u + a[u]) / n;
                u = f[u];
            }
            if(C == 0)continue;
            if(!all_even){
                both += C;
            }else{
                if(!(n & 1)){
                    if(!(i & 1)) only1 += C;
                    else only2 += C;
                }else{
                    ll hand1 = (C + (i & 1)) / 2;
                    only1 += hand1;
                    only2 += (C - hand1);
                }
            }
        }

        cout << only1 << " " << only2 << " " << both << "\n";
    }
    return 0;
}

Comments

No comments yet.