zoukankan      html  css  js  c++  java
  • 1009: Josephus环的复仇

    1009: Josephus环的复仇

    时间限制: 1 Sec  内存限制: 128 MB
    提交: 170  解决: 15
    [提交][状态][讨论版]

    题目描述

    任给正整数n、k,按下述方法可得排列1,2,……,n的一个置换:将数字1,2,.. .,n环形排列,按顺时针方向从1开始计数;计满K时输出该为之上的数字(并从环中删去该数字),然后从下一个数字开始继续计数,直到环中所有数字均被输出为止。试编写一算法,对输人的任意正整数n、k(n>=k>0),输出相应的置换。

    数据结构老师没有告诉xry111这题n、k的上限,因此xry111自作主张地认为n<=200000。请解决这一问题。

    输入

    单组数据,包含2个整数n、k(0<k<=n<=200000)。

    输出

    输出1行,包含n个整数(含义如题目描述),用空格分割。
    行末不要有多余的空格。

    样例输入

    10 3

    样例输出

    3 6 9 2 7 1 8 5 10 4

    #include<bits/stdc++.h> 
    #define REP(i,a,b) for(int i=a;i<=b;i++) 
    #define MS0(a) memset(a,0,sizeof(a)) 
    #define lson l,m,rt<<1 
    #define rson m+1,r,rt<<1|1 
      
    using namespace std; 
      
    typedef long long ll; 
    const int maxn=200100; 
    const int INF=(1<<29); 
      
    int n,k,K; 
    struct SegTree 
    { 
        int l,r; 
        int id,cnt; 
        void debug() 
        { 
            printf("%2d %2d %2d %2d
    ",l,r,id,cnt); 
        } 
    };SegTree T[maxn<<2]; 
      
    void push_up(int rt) 
    { 
        T[rt].cnt=T[rt<<1].cnt+T[rt<<1|1].cnt; 
    } 
      
    void build(int l,int r,int rt) 
    { 
        T[rt].l=l;T[rt].r=r; 
        if(l==r){ 
            T[rt].id=l; 
            T[rt].cnt=1; 
            return; 
        } 
        int m=(l+r)>>1; 
        build(lson); 
        build(rson); 
        push_up(rt); 
    } 
      
    int query(int L,int R,int l,int r,int rt) 
    { 
        if(L<=l&&r<=R) return T[rt].cnt; 
        int m=(l+r)>>1; 
        int res=0; 
        if(L<=m) res+=query(L,R,lson); 
        if(R>m) res+=query(L,R,rson); 
        return res; 
    } 
      
    void update(int p,int c,int l,int r,int rt) 
    { 
        if(l==r){ 
            T[rt].cnt=c; 
            return; 
        } 
        int m=(l+r)>>1; 
        if(p<=m) update(p,c,lson); 
        else update(p,c,rson); 
        push_up(rt); 
    } 
      
    int bin(int p,int l,int r) 
    { 
        while(l<r){ 
            int m=(l+r)>>1; 
            int ls=query(l,m,1,n,1); 
            if(p<=ls) r=m; 
            else l=m+1,p-=ls; 
        } 
        return l; 
    } 
      
    int main() 
    { 
        while(~scanf("%d%d",&n,&k)){ 
            build(1,n,1); 
            int cur=1; 
            REP(i,1,n){ 
                cur=(cur+k-1)%T[1].cnt; 
                if(cur==0) cur=T[1].cnt; 
                int p=bin(cur,1,n); 
                if(i==n) printf("%d
    ",p); 
                else printf("%d ",p); 
                update(p,0,1,n,1); 
            } 
        } 
        return 0; 
    } 
      
    /************************************************************** 
        Problem: 1009 
        User: 14030140102 
        Language: C++ 
        Result: 正确 
        Time:716 ms 
        Memory:14196 kb 
    ****************************************************************/ 
    View Code



     

    #include<bits/stdc++.h> 
    #define REP(i,a,b) for(int i=a;i<=b;i++) 
    #define MS0(a) memset(a,0,sizeof(a)) 
    #define lson l,m,rt<<1 
    #define rson m+1,r,rt<<1|1 
      
    using namespace std; 
      
    typedef long long ll; 
    const int maxn=200100; 
    const int INF=(1<<29); 
      
    int n,k; 
    int c[maxn];
    
    int lowbit(int x)
    {
        return x&(-x);
    }
    
    void add(int p,int x)
    {
        while(p<=n){
            c[p]+=x;
            p+=lowbit(p);
        }
    }
    
    int sum(int p)
    {
        int res=0;
        while(p>0){
            res+=c[p];
            p-=lowbit(p);
        }
        return res;
    }
      
    int bin(int p,int l,int r) 
    { 
        while(l<r){ 
            int m=(l+r)>>1; 
            int ls=sum(m)-sum(l-1);
            if(p<=ls) r=m; 
            else l=m+1,p-=ls; 
        } 
        return l; 
    } 
      
    int main() 
    { 
        while(~scanf("%d%d",&n,&k)){ 
            MS0(c);
            int cur=1; 
            REP(i,1,n) add(i,1);
            REP(i,1,n){ 
                int cnt=sum(n);
                cur=(cur+k-1)%cnt; 
                if(cur==0) cur=cnt; 
                int p=bin(cur,1,n); 
                if(i==n) printf("%d
    ",p); 
                else printf("%d ",p);
                int x=sum(p)-sum(p-1);
                add(p,-x); 
            } 
        } 
        return 0; 
    }
    View Code


     

    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    关于数组添加元素的优化 __原文司徒正美
    FIRST
    二维数组作为参数传递问题
    c++线程池的实现
    阻塞和非阻塞
    N皇后解决方法
    判断一棵二叉树是否为BST,一棵树是否为完全二叉树
    c++11可变参数的使用
    最大似然估计和最大后验估计
    利用Microsoft Azure Machine Learning Studio创建机器学习实例
  • 原文地址:https://www.cnblogs.com/--560/p/4947308.html
Copyright © 2011-2022 走看看