• J Josephus Transform(x次连续的k-约瑟夫变换,利用线段树找位置)


    题:https://ac.nowcoder.com/acm/contest/5671/J

    题意:初始序列为1 2 3。。。n,给定m个操作[k,x]代表对序列连续执行x次k-约瑟夫变换

    题解:

    #include <bits/stdc++.h>
    using namespace std;
    #define pb push_back
    #define MP make_pair
    #define lson root<<1,l,midd
    #define rson root<<1|1,midd+1,r
    const int M = 1e5+5;
    int tr[M<<2];
    void up(int root){
        tr[root]=tr[root<<1]+tr[root<<1|1];
    }
    void build(int root,int l,int r){
        tr[root]=0;
        if(l==r){
            tr[root]=1;
            return ;
        }
        int midd=(l+r)>>1;
        build(lson);
        build(rson);
        up(root);
    }
    void update(int pos,int root,int l,int r){
        if(l==r){
            tr[root]=0;
            return ;
        }
        int midd=(l+r)>>1;
        if(pos<=midd)
            update(pos,lson);
        else
            update(pos,rson);
        up(root);
    }
    int query(int num,int root,int l,int r){
        if(l==r)
            return l;
        int midd=(l+r)>>1;
        if(num<=tr[root<<1])
            return query(num,lson);
        else
            return query(num-tr[root<<1],rson);
    }
    ///i位置要取到a[i]位置的值
    int a[M],b[M],c[M],d[M],res[M];
    int n,m;
    int k,x;
    void quick_pow(int y){
        for(int i = 1;i <= n;i++)res[i] = i;
        while(y){
            if(y&1){
                for(int i=1;i<=n;i++)d[i]=res[i];
                for(int i=1;i<=n;i++)res[i]=d[a[i]];
            }
            ///快速幂跳转1、2、4、8....次
            for(int i=1;i<=n;i++)c[i]=a[i],d[i]=a[i];
            for(int i=1;i<=n;i++)a[i]=c[d[i]];
            y >>= 1;
        }
        return;
    }
    int main(){
        ios_base::sync_with_stdio(0);
        cin.tie(0);
        cin>>n>>m;
        for(int i=1;i<=n;i++)
            b[i] = i;
        while(m--){
            build(1,1,n);
            cin>>k>>x;
            int pos=1;
            for(int i=1;i<=n;i++){
                pos =(pos-1+k-1)%(n-i+1)+1;
                a[i]=query(pos,1,1,n);
                update(a[i],1,1,n);
            }
            quick_pow(x);
            for(int i=1;i<=n;i++)c[i]=b[i];
            for(int i=1;i<=n;i++)b[i]=c[res[i]];
        }
        for(int i=1;i<=n;i++)cout<<b[i]<<" ";
        return 0;
    }
    View Code
  • 相关阅读:
    Python为什么要self
    安全散列算法(secure hash algorithm,SHA)
    傅里叶变换

    K 最近邻(k-nearest neighbours,KNN)算法
    贪婪算法
    狄克斯特拉算法
    广度优先搜索
    快速排序
    选择排序
  • 原文地址:https://www.cnblogs.com/starve/p/13443130.html
Copyright © 2020-2023  润新知