题解(倍增解法)
2025-08-14 10:55:18
发布于:广东
0阅读
0回复
0点赞
进行第2的i次方次交换刚好为2的i-1次方交换后的队列再以2的i-1次方队列顺序交换一次后的顺序。先求出每个2^i次交换后的顺序,再根据2进制逐步交换(神奇的是,状态转移方程和LCA倍增法一模一样)
#include<bits/stdc++.h>
using namespace std;
int n,m,k,a[100005][2],dp[100005][31];
int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n>>m>>k;
int ol=1,ne=0;
for(int i=1;i<=n;++i)a[i][0]=i;
for(int i=1;i<=m;++i){
swap(ol,ne);
int x,y;
cin>>x>>y;
for(int j=1;j<=n;++j)a[j][ne]=a[j][ol];
for(int j=x;j<=y;++j){
a[j][ne]=a[y-(j-x)][ol];
}
}
for(int i=1;i<=n;++i)dp[i][0]=a[i][ne];
for(int i=1;(1<<i)<=k;++i){
for(int j=1;j<=n;++j){
dp[j][i]=dp[dp[j][i-1]][i-1];
}
}
int num=0,cnt=0;
while(k){
if(k%2==1){
cnt++;
swap(ol,ne);
if(cnt==1){
for(int i=1;i<=n;++i)a[i][ne]=dp[i][num];
}
else{
for(int j=1;j<=n;++j){
a[j][ne]=dp[a[j][ol]][num];
}
}
}
num++;
k/=2;
}
for(int i=1;i<=n;++i){
cout<<a[i][ne]<<"\n";
}
return 0;
}
这里空空如也
有帮助,赞一个