1521. War Games 2(线段树解约瑟夫)

1521

根据区间和 来确定第k个数在哪

 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 }
View Code

 

你可能感兴趣的:(games)