1521. War Games 2(线段树解约瑟夫)
根据区间和 来确定第k个数在哪
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 using namespace std; 7 #define N 100010 8 int s[N<<2],tt; 9 void up(int w) 10 { 11 s[w] = s[w<<1]+s[w<<1|1]; 12 } 13 void build(int l,int r,int w) 14 { 15 if(l==r) 16 { 17 s[w] = 1; 18 return ; 19 } 20 int m = (l+r)>>1; 21 build(l,m,w<<1); 22 build(m+1,r,w<<1|1); 23 up(w); 24 } 25 void update(int k,int l,int r,int w) 26 { 27 if(l==r) 28 { 29 s[w] = 0; 30 tt = l; 31 return ; 32 } 33 int m = (l+r)>>1; 34 if(k<=s[w<<1]) 35 update(k,l,m,w<<1); 36 else 37 update(k-s[w<<1],m+1,r,w<<1|1); 38 up(w); 39 } 40 int getsum(int a,int b,int l,int r,int w) 41 { 42 if(a<=l&&b>=r) 43 { 44 return s[w]; 45 } 46 int m = (l+r)>>1,re=0; 47 if(a<=m) 48 re+=getsum(a,b,l,m,w<<1); 49 if(b>m) 50 re+=getsum(a,b,m+1,r,w<<1|1); 51 return re; 52 } 53 int main() 54 { 55 int k,n,o=0,ss=0; 56 scanf("%d%d",&n,&k); 57 build(1,n,1); 58 int m = n; 59 while(n) 60 { 61 if(tt) 62 { 63 ss = getsum(1,tt,1,m,1); 64 o = (k+ss)%s[1]; 65 } 66 else 67 o = k%s[1]; 68 if(o==0) 69 o=s[1]; 70 update(o,1,m,1); 71 n--; 72 if(n) 73 printf("%d ",tt); 74 else 75 printf("%d\n",tt); 76 } 77 return 0; 78 }