倍增题目
太卡时间了,没意思
定义st[i][j]表示从i位置 进行了次操作后的下标,为什么是下标呢?
我一开始定义的是i位置进行了次次操作后的值,但是发现如果是值的话,转移方程写不了
如果是下标,那么转移时,直接就是,初始化st[i][0] = x[i]
所以可以很快的写完代码:
#include<bits/stdc++.h>
using namespace std;

#define endl '\n'
#define ll long long
#define IOS ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define HelloWorld IOS;


const int N = 2e5 + 10;
const int M = 63;

int n;
ll k;
int st[N][M];
int x[N], a[N];

int main(){
    HelloWorld;
    
    cin >> n >> k;
    for(int i = 1; i <= n; i ++) cin >> x[i];
    for(int i = 1; i <= n; i ++) cin >> a[i];
    for(int i = 1; i <= n; i ++) st[i][0] = x[i];
    for(int j = 1; j < M; j ++){
        for(int i = 1; i <= n; i ++) st[i][j] = st[st[i][j - 1]][j - 1];
    }
    for(int i = 1; i <= n; i ++){
        ll k1 = k;
        int pos = i;
        for(int j = M - 1; j >= 0; j --){
            if(k1 >= (ll)(1LL << j)){
                k1 -= (ll)(1LL << j);
                pos = st[pos][j];
            }
        }
        cout << a[pos] << " ";
    }
    cout << endl;
    return 0;
}
通过率有90%,但是超时了,然后看题解修一点,交一发超时,修一点交一发超时....
最后的通过代码:
#include<iostream>
#include<vector>

using namespace std;


const int M = 60;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    int n;
    long long k;
    scanf("%d %lld", &n, &k);
    vector<int> a(n + 1);
    vector<vector<int> > st(M + 1, vector<int> (n + 1));
    for(int i = 1; i <= n; ++ i) scanf("%d", &st[0][i]);
    for(int i = 1; i <= n; ++ i) scanf("%d", &a[i]);
    for(int j = 1; j < M; ++ j){
        for(int i = 1; i <= n; ++ i) st[j][i] = st[j - 1][st[j - 1][i]];
    }
    vector<int> ans(n + 1);
    for(int i = 1; i <= n; ++ i){
        int pos = i;
        for(int j = M - 1; j >= 0; -- j){
            if((k >> j) & 1) pos = st[j][pos];
        }
        ans[i] = a[pos];
    }
    for(int i = 1; i <= n; ++ i){
        printf("%d ", ans[i]);
    }
    printf("\n");
    
    return 0;
}
超时的代码时间复杂度为,最大为级别也会超时,真勾石
题解里有一篇:滚动数组来优化的:替代了,大大减小了时间复杂度
真的厉害%%%
#include<bits/stdc++.h>
using namespace std;

#define endl '\n'
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define HelloWorld IOS;


const int N = 2e5 + 10;

int n, k;
int st[N][2], a[N], idx[N];
signed main(){
    HelloWorld;
    
    cin >> n >> k;
    for(int i = 1; i <= n; i ++){
        cin >> st[i][0];
        if(k & 1) idx[i] = st[i][0];
        else idx[i] = i;
    }
    k >>= 1;
    for(int i = 1; i <= n; i ++) cin >> a[i];
    for(int j = 1; k; k >>= 1, j ^= 1){
        for(int i = 1; i <= n; i ++) st[i][j] = st[st[i][j ^ 1]][j ^ 1];
        if(k & 1){
            for(int i = 1; i <= n; i ++) idx[i] = st[idx[i]][j];
        }
    }
    for(int i = 1; i <= n; i ++) cout << a[idx[i]] << " ";
    cout << endl;
    return 0;
}