優化-T2078 HKE與他的小朋友
阿新 • • 發佈:2018-11-11
題目連結:https://www.luogu.org/problemnew/show/T2078
題目背景
HKE帶著nn個小朋友做遊戲
題目描述
現在有n個座位編號為11至nn,這些小朋友也編號11至nn。一開始所有小朋友都坐在相應的座位上。HKE的遊戲可用一個n的排列A(A_1,A_2\cdots _nA(A 1 ,A 2 ⋯A n )表示。一輪遊戲時,對於所有的1\leq i\leq n1≤i≤n,坐在位置ii上的小朋友坐到位置A_iA i 上。
現在遊戲進行了kk輪,HKE想知道遊戲結束後,位置1,2\cdots n1,2⋯n分別坐了幾號小朋友?
輸入輸出格式
輸入格式:
第一行n,kn,k。
第二行A_1,A_2\cdots A_nA 1 ,A 2 ⋯A n
輸出格式:
一行n個數表示位置1,2……n1,2……n上的小朋友的編號
輸入輸出樣例
輸入樣例#1: 複製
5 5
2 3 1 5 4
輸出樣例#1: 複製
2 3 1 5 4
輸入樣例#2: 複製
5 4
2 3 1 5 4
輸出樣例#2: 複製
3 1 2 4 5
說明
30%的資料,n\leq1000n≤1000,k\leq1000k≤1000
100%的資料,n\leq100000n≤100000,k\leq2^{31}-1k≤2
31
−1
一開始打了個30分程式碼如下:
#include<iostream> #include <algorithm> using namespace std; int k,n,a[100010],b[100010],c[100010]; int main() { cin>>n>>k; for (int i=1;i<=n;i++) { cin>>a[i]; b[i]=i; } for (int i=1;i<=k;i++) { for (int j=1;j<=n;j++) { c[a[j]]=b[j]; } for (int j=1;j<=n;j++) { b[j]=c[j]; cout<<b[j]<<" "; } cout<<endl; } // for (int j=1;j<=n;j++) // { // cout<<b[j]<<" "; // } return 0; }
大神給了個AC程式碼如下,仰望大神啊。
#include <iostream> #include <cmath> using namespace std; int main() { int A[100001]; int s[100001],t[100001]; long long n,k; long long m,p,q,r; cin >> n >> k; for(long long i=1;i<=n;i++){ cin >> A[i]; s[i]=0; } for(long long i=1;i<=n;i++){ if(s[i]>0) continue; m=0; p=i; t[0]=i; do{//計算單個數重複週期 p=A[p]; m++; t[m]=p; }while(p!=i); q=k%m; p=i; do{//全環設定 r=t[q]; s[r]=p; p=A[p]; q++; q=q%m; }while(p!=i); } for(long long i=1;i<=n;i++){ cout << s[i] << " "; } return 0; }