0%

ABC377-E-Permute K times 2

AC代码

这题面说起来也简单,就是P1=5 那我就用P5代替你———同理 所有的Pi都要进行这个操作

题意很简单,就是操作数很大,不可能模拟。

那我们的问题就变成了这个变化有什么规律吗?

image

一个非常详细的题解

image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <cstring>
#include <algorithm>
#include <deque>
#include <queue>
#include <vector>
#include <set>
#include <cmath>
#include <bitset>
using namespace std;
typedef long long ll;
const ll N=2e5+10;
ll n,p[N],k,ans[N],cnt,ring[N],d[N];
bool vis[N];
vector<ll> g[N];
void dfs(ll i,ll dis) {
if(vis[i]) {
return;
}
vis[i]=true;
g[cnt].push_back(i);
ring[i]=cnt,d[i]=dis;
dfs(p[i],dis+1);
}
ll binpow(ll a,ll b,ll p) {
if(b==0) return 1;
ll res=binpow(a,b/2,p)%p;
if(b%2) // b%2!=0
return res%p*res%p*a%p; // 毕竟res是
else
return res%p*res%p;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>k;
for(int i=1;i<=n;i++) {
cin>>p[i];
if(p[i]==i)
ans[i]=i;
}
for(int i=1;i<=n;i++) {
if(ans[i]!=0) // 这相当于一个自环,倒也不用走
continue;
if(vis[i]) // 走过了,不用处理
continue;
cnt++;
dfs(i,0);
}
// 答案解决阶段
for(int i=1;i<=n;i++) {
if(ans[i]!=0) // 答案都确定了也就无所谓了
continue;
ll ringSize=g[ring[i]].size();
ll advStep=binpow(2,k,ringSize);
ans[i]=g[ring[i]][(d[i]+advStep)%ringSize];
}
for(int i=1;i<=n;i++) {
cout<<ans[i]<<" ";
}
cout<<endl;
return 0;
}
// AC https://atcoder.jp/contests/abc377/submissions/59254380

心路历程(WA,TLE,MLE……)

挺难想的,实现起来其实也比较难,还需要快速幂,但确实是一次提交AC,只能说我的图论代码实现水平还是比较高的