(紀中)2410. Swapity Swap【快速冪】

(File IO): input:swap.in output:swap.out
時間限制: 1000 ms 空間限制: 262144 KB 具體限制
Goto ProblemSet


題目描述
FarmerJohnFarmer JohnNN 頭奶牛1N105)(1≤N≤10^5)站成一排。對於每一個 1iN1≤i≤N,從左往右數第 ii頭奶牛的編號爲 iiFarmerJohnFarmer John 想到了一個新的奶牛晨練方案。他給奶牛們 MM 對整數 (L1,R1)(LM,RM)(L1,R1)…(LM,RM),其中 1M1001≤M≤100。他讓她們重複以下包含 MM 個步驟的過程 K1K109)K(1≤K≤10^9)次:
對於從 11MM 的每一個步驟i:當前從左往右數在位置 LiRiLi…Ri 的奶牛序列反轉她們的順序。
當奶牛們重複這一過程KK 次後,請對每一個 1≤i≤N 輸出從左往右數第ii 頭奶牛的編號。


輸入
輸入的第一行包含 N,MN, MKK。對於每一個 1iM1≤i≤M,第i+1i+1 行包含 LiLiRiRi,均爲範圍在 1N1…N 內的整數,其中 Li<Ri。

輸出
在第 ii 行輸出指令序列執行了 KK 次後奶牛序列中從左往右數第 ii個元素的編號。


樣例輸入
7 2 2
2 5
3 7

樣例輸出
1
2
4
3
5
7
6


數據範圍限制
測試點 121-2 滿足N=K=100N=K=100
測試點 353-5 滿足 K103K≤10^3
測試點 6106-10 沒有額外限制。


提示
初始時,奶牛們的順序從左往右爲[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,7,6,2,3,4][1,5,7,6,2,3,4]。再重複這兩個步驟各一次可以得到樣例的輸出。


解題思路
對於初始的序列 1N1-N 我們可以把它看作數組的位置下標,那麼每次操作不就是調換位置,不用管此時在這個位置上的數,也就是我們只要得出進行 M 次操作後第 ii 位會換到的位置並標記,每一輪結束後就只用調位置就行了,不用再模擬一遍 MM

  • 拿樣例來解釋:
    初始序列爲 1,2,3,4,5,6,71,2,3,4,5,6,7
    先處理出進過 MM 次得出的序列爲 1,5,7,6,2,3,41,5,7,6,2,3,4
    可以得出1>12>53>64>75>26>47>31->1,2->5,3->6,4->7,5->2,6->4,7->3
    上面的數字全都代表數組下標,比如下標22上的數變到了下標55
    那麼第二輪就是 1,5,7,6,2,3,41,5,7,6,2,3,4 中,位置11上的數不變,
    位置22上的數到了位置55,位置33上的數到了位置66……
    則最後序列就變爲 1,2,4,3,5,7,61,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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章