zoukankan      html  css  js  c++  java
  • 2020牛客暑期多校训练营(第六场)J-Josephus Transform 群置换,约瑟夫环

    J-Josephus Transform

    题意

    对排列(P=left{ 1,2,dots,n ight})(m)次操作,每次操作给一对数(k,x),表示对(P)(x)次步长为(k)的约瑟夫变换,求出最终的(P)排列。

    分析

    先考虑如何求一个(k)-约瑟夫变换,注意每次取出的数字是剩下的几个数字中的第几个是可以算出来的,设上一次被取出的数字是当时的第(pos)个(初始设为 (1)),当前还剩下 (cnt) 个数字,那么下一 个被选出来的数应该是当前剩下的所有数字中的第 ((pos-1+k-1) \% cnt + 1) 个,用线段树来求编号为(k)的数,对数字从(1sim n)建线段树,初始值都为(1),被取出后置为(0),编号为(k)的数即为前缀和等于(k)的位置,可以在线段树上二分求出。

    求出(k)-约瑟夫变换后,就可以对(P)做置换了,群置换是满足结合律的,所以可以用快速幂来算,设(k)-约瑟夫变换排列为(a),把置换看做乘法,那么对(P)(x)次置换即为(P cdot a^x),快速幂求出(a^x),然后再用(a^x)(P)做一次置换就可以了。

    Code

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<iomanip>
    #include<sstream>
    #include<cstdio>
    #include<string>
    #include<vector>
    #include<bitset>
    #include<queue>
    #include<cmath>
    #include<stack>
    #include<set>
    #include<map>
    #define rep(i,x,n) for(int i=x;i<=n;i++)
    #define per(i,n,x) for(int i=n;i>=x;i--)
    #define sz(a) int(a.size())
    #define rson mid+1,r,p<<1|1
    #define pii pair<int,int>
    #define lson l,mid,p<<1
    #define ll long long
    #define pb push_back
    #define mp make_pair
    #define se second
    #define fi first
    using namespace std;
    const double eps=1e-8;
    const int mod=1e9+7;
    const int N=1e6+10;
    const int inf=1e9;
    int n,m;
    int tr[N<<2],a[N],A[N],B[N],tmp[N];
    void bd(int l,int r,int p){
        if(l==r) return tr[p]=1,void();
        int mid=l+r>>1;
        bd(lson);bd(rson);
        tr[p]=tr[p<<1]+tr[p<<1|1];
    }
    void up(int x,int l,int r,int p){
        if(l==r) return tr[p]=0,void();
        int mid=l+r>>1;
        if(x<=mid) up(x,lson);
        else up(x,rson);
        tr[p]=tr[p<<1]+tr[p<<1|1];
    }
    int find(int x,int l,int r,int p){
        if(l==r) return l;
        int mid=l+r>>1;
        if(tr[p<<1]<x) return find(x-tr[p<<1],rson);
        else return find(x,lson);
    }
    void change(int k){
        bd(1,n,1);
        int pos=1;
        rep(i,1,n){
            pos=(pos+k-2)%(n-i+1)+1;
            int x=find(pos,1,n,1);
            a[i]=x;
            up(x,1,n,1);
        }
    }
    void mul(int a[],int b[]){
        rep(i,1,n) tmp[i]=a[b[i]];
        rep(i,1,n) a[i]=tmp[i];
    }
    void ksm(int x){
        rep(i,1,n) B[i]=i;
        while(x){
            if(x&1) mul(B,a);
            x>>=1;
            mul(a,a);
        }
    }
    int main(){
        //ios::sync_with_stdio(false);
        //freopen("in","r",stdin);
        scanf("%d%d",&n,&m);
        rep(i,1,n) A[i]=i;
        while(m--){
            int k,x;
            scanf("%d%d",&k,&x);
            change(k);
            ksm(x);
            mul(A,B);
        }
        rep(i,1,n) printf("%d%c",A[i],i==n?'
    ':' ');
        return 0;
    }
    
    
  • 相关阅读:
    ABAP开发常见任务
    sap smartform 打印乱码问题
    根据T-Code查看用户出口的代码
    java 调用SAP RFC函数错误信息
    代码单行超过72个字符的一个异常
    SAP 权限层次
    标准屏幕字段描述修改
    [转]SAP一句话入门SD模块
    Python3.7,os模块
    Python3,逻辑运算符
  • 原文地址:https://www.cnblogs.com/xyq0220/p/13494076.html
Copyright © 2011-2022 走看看