倍增题目
太卡时间了,没意思
定义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;
}



京公网安备 11010502036488号