1. 程式人生 > >省選模擬賽 環

省選模擬賽 環

while nbsp mic pri spa name AI sans pac

技術分享圖片

分析:不算太難的一道題.

   如果把每個編號i看作一個點,i向ai連邊,那麽最後一定會出現環,並且環與環之間是不相交的. 那麽我們可以dfs預處理出所有的環,用詢問的m除以環的長度,剩下的余數就可以O(1)計算了,時間復雜度O(n).

   上面這種做法在處理余數部分時比較容易寫錯. 一種不容易寫錯的方法是倍增. 復雜度O(nlogn),可以通過本題.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int maxn = 100010; int n,fa[maxn][20],vis[maxn]; void solve(int x,int y) { for (int i = 0; i < 19; i++) if (y & (1 << i)) x = fa[x][i]; printf("%d\n",x); } int main() { int x; while (scanf("%d",&x) != EOF && !vis[x]) { fa[++n][0
] = x; vis[x] = 1; } for (int j = 1; j <= 19; j++) for (int i = 1; i <= n; i++) fa[i][j] = fa[fa[i][j - 1]][j - 1]; int t; scanf("%d",&t); solve(x,t); while (scanf("%d%d",&x,&t) == 2) solve(x,t); return 0; }

省選模擬賽 環