(纪中)2410. Swapity Swap【快速幂】

(File IO): input:swap.in output:swap.out
时间限制: 1000 ms 空间限制: 262144 KB 具体限制
Goto ProblemSet


题目描述
F a r m e r J o h n Farmer John FarmerJohn N N N 头奶牛 ( 1 ≤ N ≤ 1 0 5 ) (1≤N≤10^5) 1N105)站成一排。对于每一个 1 ≤ i ≤ N 1≤i≤N 1iN,从左往右数第 i i i头奶牛的编号为 i i i F a r m e r J o h n Farmer John FarmerJohn 想到了一个新的奶牛晨练方案。他给奶牛们 M M M 对整数 ( L 1 , R 1 ) … ( L M , R M ) (L1,R1)…(LM,RM) (L1,R1)(LM,RM),其中 1 ≤ M ≤ 100 1≤M≤100 1M100。他让她们重复以下包含 M M M 个步骤的过程 K ( 1 ≤ K ≤ 1 0 9 ) K(1≤K≤10^9) K1K109)次:
对于从 1 1 1 M M M 的每一个步骤i:当前从左往右数在位置 L i … R i Li…Ri LiRi 的奶牛序列反转她们的顺序。
当奶牛们重复这一过程 K K K 次后,请对每一个 1≤i≤N 输出从左往右数第 i i i 头奶牛的编号。


输入
输入的第一行包含 N , M N, M N,M K K K。对于每一个 1 ≤ i ≤ M 1≤i≤M 1iM,第 i + 1 i+1 i+1 行包含 L i Li Li R i Ri Ri,均为范围在 1 … N 1…N 1N 内的整数,其中 Li

输出
在第 i i i 行输出指令序列执行了 K K K 次后奶牛序列中从左往右数第 i i i个元素的编号。


样例输入
7 2 2
2 5
3 7

样例输出
1
2
4
3
5
7
6


数据范围限制
测试点 1 − 2 1-2 12 满足 N = K = 100 N=K=100 N=K=100
测试点 3 − 5 3-5 35 满足 K ≤ 1 0 3 K≤10^3 K103
测试点 6 − 10 6-10 610 没有额外限制。


提示
初始时,奶牛们的顺序从左往右为 [ 1 , 2 , 3 , 4 , 5 , 6 , 7 ] [1,2,3,4,5,6,7] [1,2,3,4,5,6,7]。在这一过程的第一步过后,顺序变为 [ 1 , 5 , 4 , 3 , 2 , 6 , 7 ] [1,5,4,3,2,6,7] [1,5,4,3,2,6,7]。在这一过程的第二步过后,顺序变为 [ 1 , 5 , 7 , 6 , 2 , 3 , 4 ] [1,5,7,6,2,3,4] [1,5,7,6,2,3,4]。再重复这两个步骤各一次可以得到样例的输出。


解题思路
对于初始的序列 1 − N 1-N 1N 我们可以把它看作数组的位置下标,那么每次操作不就是调换位置,不用管此时在这个位置上的数,也就是我们只要得出进行 M 次操作后第 i i i 位会换到的位置并标记,每一轮结束后就只用调位置就行了,不用再模拟一遍 M M M

  • 拿样例来解释:
    初始序列为 1 , 2 , 3 , 4 , 5 , 6 , 7 1,2,3,4,5,6,7 1,2,3,4,5,6,7
    先处理出进过 M M M 次得出的序列为 1 , 5 , 7 , 6 , 2 , 3 , 4 1,5,7,6,2,3,4 1,5,7,6,2,3,4
    可以得出 1 − > 1 , 2 − > 5 , 3 − > 6 , 4 − > 7 , 5 − > 2 , 6 − > 4 , 7 − > 3 1->1,2->5,3->6,4->7,5->2,6->4,7->3 1>12>53>64>75>26>47>3
    上面的数字全都代表数组下标,比如下标 2 2 2上的数变到了下标 5 5 5
    那么第二轮就是 1 , 5 , 7 , 6 , 2 , 3 , 4 1,5,7,6,2,3,4 1,5,7,6,2,3,4 中,位置 1 1 1上的数不变,
    位置 2 2 2上的数到了位置 5 5 5,位置 3 3 3上的数到了位置 6 6 6……
    则最后序列就变为 1 , 2 , 4 , 3 , 5 , 7 , 6 1,2,4,3,5,7,6 1,2,4,3,5,7,6

代码

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#include<iomanip>
#include<cmath>
#include<set>
using namespace std;
int l,r,a[100010],b[100010],c[100010];
int n,m,k;
int main()
{
    freopen("swap.in","r",stdin);
    freopen("swap.out","w",stdout);
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n;i++)
        a[i]=i;
    while(m--){
        cin>>l>>r;
        for(int i=l;i<=r;i++)
            b[i]=a[l+r-i];
        for(int i=l;i<=r;i++)
            a[i]=b[i];
    }
    for(int i=1;i<=n;i++){
        c[i]=a[i];
        a[i]=i;
    }
    while(k>0){
        if(k&1){
            for(int i=1;i<=n;i++)
                a[i]=c[a[i]];
        }
        for(int i=1;i<=n;i++)
            b[i]=c[c[i]];
        for(int i=1;i<=n;i++)
            c[i]=b[i];
        k/=2;
    }
    for(int i=1;i<=n;i++)
        printf("%d\n",a[i]);
	return 0;
}

你可能感兴趣的:(纪中,快速幂)