D. Infinite Path (dfs, thinking)

Title: Portal

The meaning of problems

To give you a length n permutation p, and a length of n array of colors c, define an unlimited path is i, p [i], p [p [i]], p [p [p [i]]] and c [i] = c [p [i]] = c [p [p [i]]] = .........; c a sorting arrangement and the arrangement obtained by multiplying b, c satisfies [i] = b [a [i]], k p of the power arrangement, p ^ k = p * p * p * p (k p a), the minimum you ask how much non-0 k, such that p ^ k a i satisfies infinite path exists.

Thinking

Unlimited path must be a loop, we arranged given directed graph into p, then the resulting graph consists of a number of disjoint rings, we have attached to one side of the i and p [i], by dfs find all the rings.

Suppose now that there is a length of the ring tot tmp, for the first element tmp [1], when p becomes p ^ k, then the ring will be divided into a plurality of loops, for example, when k = 2, tmp [1 ] = tmp [tmp [1]], the equivalent of a two-step jump, then if tot% 2 == 0, then the length of the ring to turn tot length into two rings tot / 2 in. So, we enumerate tot factor, and then determine what, after the ring is divided into many sub-ring, if there is an infinite path i meet, the answer to maintaining a minimum, on the line.

 

#include <bits/stdc++.h>
#define LL long long
#define ULL unsigned long long
#define mem(i, j) memset(i, j, sizeof(i))
#define rep(i, j, k) for(int i = j; i <= k; i++)
#define dep(i, j, k) for(int i = k; i >= j; i--)
#define pb push_back
#define make make_pair
#define INF INT_MAX
#define inf LLONG_MAX
#define PI acos(-1)
#define fir first
#define sec second
using namespace std;

const int N = 1e6 + 5;

const LL mod = 998244353;

LL ksm(LL a, LL b) { LL ans = 1LL; while(b) { if(b & 1) ans = ans * a % mod; a = a * a % mod; b >>= 1; }  return ans; }

int a[N], c[N], tmp[N], ans, tot;

bool vis[N];

bool judge(int x, int y) {
    for(int i = 1; i <= x; i++) {
        int t = i; bool flag = 0;
        for(int j = 1; j <= y; j++) {
            if(c[tmp[t]] != c[tmp[i]]) {
                flag = 1; break;
            }
            t = (t + x - 1) % tot + 1;
        }
        if(!flag) return 1;
    }
    return 0;
}

void dfs(int x) {
    tot = 0;

    tmp[++tot] = x; vis[x] = 1;

    for(int i = a[x]; i != x; i = a[i]) tmp[++tot] = i, vis[i] = 1;

    for(int i = 1; i * i <= tot; i++) {
        if(tot % i == 0) {
            if(judge(i, tot / i)) {
                ans = min(ans, i);
                return ;
            }
            if(judge(tot / i, i)) ans = min(ans, tot / i);
        }
    }
}

void solve() {

    int n;
    scanf("%d", &n);

    rep(i, 1, n) scanf("%d", &a[i]);
    rep(i, 1, n) scanf("%d", &c[i]);

    ans = INF;

    rep(i, 1, n) if(!vis[i]) dfs(i);

    rep(i, 1, n) vis[i] = 0;

    printf("%d\n", ans);

}


int main() {
    int _; scanf("%d", &_);
    while(_--) solve();


//    solve();

    return 0;
}

 

Guess you like

Origin www.cnblogs.com/Willems/p/12561769.html