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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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\n",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\n",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 ****************************************************************/
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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\n",p); else printf("%d ",p); int x=sum(p)-sum(p-1); add(p,-x); } } return 0; }
没有AC不了的题,只有不努力的ACMER!