ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2020-07-27 21:00:19  阅读:293  来源: 互联网

标签:第六场 Josephus int mid pos 多校 牛客 maxn Find


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\n",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\n",p[n]);
    }
    for(int i=1;i<n;i++) printf("%d ",p[i]);
    printf("%d\n",p[n]);
}
/*
4 1
2 1

*/



标签:第六场,Josephus,int,mid,pos,多校,牛客,maxn,Find
来源: https://www.cnblogs.com/EchoZQN/p/13387599.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有