• jzoj 5561. 简单模拟


    Description

    很久很久以前,有一个1~n 的排列a,还有一个长度为q 的,每个元素在1
    到n 之间的序列b[0]…b[q-1]。
    作为一道简单模拟题,你需要模拟m 次操作,第i(1 到m)次操作你会在
    a 中找到值为b[(i-1)%q]的元素,并把它与第一个元素交换。
    你只需要输出m 次操作之后的序列即可
     

    Input

    第一行三个整数n、q、m。
    第二行n 个整数表示排列a。
    第二行q 个整数表示序列b。

    Output

    一行n 个整数,表示m 次操作后的排列。
     
     Data Constraint
     Subtask 1,10pts,1<=n,q,m<=100。
     Subtask 2,10pts,1<=n,q,m<=5000。
     Subtask 3,20pts,1<=n=q<=5000,1<=m<=10^18,b[i]=i+1。
     Subtask 4,20pts,1<=n=q<=200000,1<=m<=10^18,b[i]=i+1。
     Subtask 5,40pts,1<=n,q<=200000,1<=m<=10^18。
    SOL :发现这是一个置换,那么,我们把n次操作看成一个置换,对其快速幂,再暴力。
    #include<bits/stdc++.h>
    using namespace std;
    #define N 200007
    struct Node{
        int siz,a[N];
        void init(int n){
            siz=n;
            for (int i=1;i<=n;i++) a[i]=i;
        }
        void res() {
            static Node xxoo;
            xxoo=*this;
            for (int i=1;i<=siz;i++) a[xxoo.a[i]]=i;
        }
    }C,anw;
    #define sight(x) ('0'<=x&&x<='9')
    template <class T>
    inline void read(T &x){
        static char c;
        for (c=getchar();!sight(c);c=getchar());
        for (x=0;sight(c);c=getchar())x=x*10+c-48;
    }
    void write(int x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);}
    inline void writeln(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar('
    '); }
    inline void writel(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar(' '); }
    Node operator * (const Node x,const Node y){
         Node anw;
         anw.siz=x.siz;
         for (int i=1;i<=x.siz;i++) anw.a[i]=y.a[x.a[i]];
         return anw; 
    }
    long long m,y;
    int n,q,a[N],b[N],st,pos[N],top,ang[N],ans[N];
    signed main () {
        freopen("sim.in","r",stdin);
        read(n); read(q); read(m);
        for (int i=1;i<=n;i++) read(a[i]);
        for (int i=0;i<q;i++) read(b[i]);
        for (int i=1;i<=n;i++) pos[a[i]]=i;
        C.init(n); m--;
        for (int i=1;i<q;i++)  swap(C.a[b[i-1]],C.a[b[i]]);
        swap(C.a[b[0]],C.a[b[q-1]]);
        C.res();
        for (anw.init(n),y=m/q;y;y>>=1,C=C*C) 
           if (y&1) anw=anw*C;
        C=anw;
        C.res();
        m%=q;  
        for (int i=1;i<=m;i++) swap(C.a[b[i-1]],C.a[b[i]]);
        C.res();
        swap(pos[a[1]],pos[b[0]]);
        for (int i=1;i<=n;i++) ang[C.a[i]]=pos[i];
        for (int i=1;i<=n;i++) ans[ang[i]]=i;
        for (int i=1;i<=n;i++) writel(ans[i]);
    }
      
  • 相关阅读:
    324. Wiggle Sort II
    341. Flatten Nested List Iterator
    300. Longest Increasing Subsequence
    72. Edit Distance
    63. Unique Paths II
    221.Maximal Square
    House Robbers. 198 & 213
    [C++] 与比较有关的事情
    218.The Skyline Problem
    41. First Missing Positive
  • 原文地址:https://www.cnblogs.com/rrsb/p/9867349.html
Copyright © 2020-2023  润新知