zoukankan      html  css  js  c++  java
  • 2020牛客暑期多校训练营(第六场) Josephus Transform

    2020牛客暑期多校训练营(第六场) Josephus Transform

    题解:

    这个和之前牛客的一个题目很像

    2020牛客暑期多校训练营(第二场) [Just Shuffle]

    会做那个之后,这个你只要发现这个找操作就是一种置换,所以可以找到这个置换数组,这个应该是这个题目的难点,可以用二分+树状数组找到这个置换数组,然后就是多次进行置换即可。

    严格来说这个题目其实比第二场的这个题目简单很多,但是时间不够,没写出来。

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 2e5+10;
    int p[maxn],a[maxn],c[maxn],n,f[maxn],cnt[maxn],b[maxn];
    int lowbit(int x){
        return x&(-x);
    }
    void updata(int i,int k){    //??i????????k
        while(i <= n){
            c[i] += k;
            i += lowbit(i);
        }
    }
    int getsum(int i){        //?¡§?A[1 - i]????
        int res = 0;
        while(i > 0){
            res += c[i];
            i -= lowbit(i);
        }
        return res;
    }
    int Find(int x){
        return x==f[x]?x:f[x]=Find(f[x]);
    }
    int main(){
        int m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) b[i]=i;
        while(m--){
            int k,x;
            scanf("%d%d",&k,&x);
            for(int i=1;i<=n;i++) c[i]=0,f[i]=i,cnt[i]=0;
            for(int i=1;i<=n;i++) updata(i,1);
            int l = 1;
            for(int i=1;i<=n;i++){
                int now = n-i+1;
                int sum = getsum(n)-getsum(l-1),cur = k;
                if(now<k) cur = k%now;
                if(!cur) cur+=now;
                if(sum<cur) cur = cur-sum,l = 1;
                int lc = 1,rc = n,res = getsum(l-1),pos=0;
                while(lc<=rc) {
                    int mid = (lc + rc) >> 1;
                    int sum1 = getsum(mid) - res;
                    if (sum1 >= cur) rc = mid - 1,pos=mid;
                    else lc = mid + 1;
                }
                a[i]=pos;
                updata(pos,-1);
                l = pos;
                if(Find(i)!=Find(pos)) f[i]=pos;
            }
    //        for(int i=1;i<=n;i++) printf("a[%d]=%d
    ",i,a[i]);
            for(int i=1;i<=n;i++) cnt[Find(i)]++;
            for(int i=1;i<=n;i++) {
                if (!cnt[i]) continue;
                int len = cnt[i], w = i, now = i;
                int num = x % len;
                for (int j = 1; j <= num; j++) w = a[w];
                for (int j = 1; j <= len; j++) {
                    p[now] = b[w];
                    w = a[w], now = a[now];
                }
            }
            for(int i=1;i<=n;i++) b[i]=p[i];
    //        for(int i=1;i<n;i++) printf("%d ",p[i]);
    //    	printf("%d
    ",p[n]);
        }
        for(int i=1;i<n;i++) printf("%d ",p[i]);
        printf("%d
    ",p[n]);
    }
    /*
    4 1
    2 1
    
    */
    
    
    
    
  • 相关阅读:
    YApi 部署记录
    《Go语言网络编程》第一章:体系
    Golang知识图谱
    Docker学习笔记之二:制作镜像并PUSH
    下载m3u8视频
    杂知识
    遗传算法
    评分卡
    小数据玩转Pyspark(2)
    从Word Embedding到Bert模型—自然语言处理中的预训练技术发展史(转载)
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/13387599.html
Copyright © 2011-2022 走看看