poj2886Who Gets the Most Candies? (约瑟夫环)

http://poj.org/problem?id=2886

单点更新 初始位置都是1 如果这个人出去 位置变为0 利用线段树求区间k值 k值的计算如下

如果这个数值是负的 那么下一个人的就是((k-1+p[id].d)%n+n)%n+1; 如果是正的 下一个人就是(k-1+p[id].d-1)%n+1; 

 1 #include <cstdio>

 2 #include <cstring>

 3 #include <algorithm>

 4 #include<stdlib.h>

 5 #include<iostream>

 6 #include<cmath>

 7 using namespace std;

 8 #define N 500010

 9 struct node

10 {

11     char s[12];

12     int d;

13 }p[N];

14 int s[N<<2],n,k,num,o[N],maxz,kk,key;

15 int a[37]={1,2,4,6,12,24,36,48,60,120,180,240,360,720,840,1260,1680,2520,5040,7560,10080,15120,20160,25200,27720,45360,50400,

16            55440,83160,110880,166320,221760,277200,332640,498960,500001};

17 int b[37]={1,2,3,4,6,8,9,10,12,16,18,20,24,30,32,36,40,48,60,64,72,80,84,90,96,100,108,120,128,144,160,168,180,192,200,1314521};

18 void build(int l,int r,int w)

19 {

20     if(l==r)

21     {

22         s[w] = 1;

23         return ;

24     }

25     int m = (l+r)>>1;

26     build(l,m,w<<1);

27     build(m+1,r,w<<1|1);

28     s[w] = s[w<<1]+s[w<<1|1];

29 }

30 void update(int p,int l,int r,int w)

31 {

32     if(l==r)

33     {

34         s[w] = 0;

35         key = l;

36         return ;

37     }

38     int m = (l+r)>>1;

39     if(p<=s[w<<1])

40     update(p,l,m,w<<1);

41     else

42     update(p-s[w<<1],m+1,r,w<<1|1);

43     s[w] = s[w<<1] + s[w<<1|1];

44 }

45 int main()

46 {

47     int i,j,sum;

48     while(scanf("%d%d",&n,&k)!=EOF)

49     {

50         kk=0;i=0;maxz=0;

51         while(a[i]<=n) i++;

52         kk = a[i-1];

53         maxz = b[i-1];

54         int nn = n;

55         build(1,n,1);

56         for(i = 1 ;i <= n ; i++)

57         scanf("%s%d",p[i].s,&p[i].d);

58         int id;

59         for(i = 0 ; i < kk ; i++)

60         {

61             n--;

62             update(k,1,nn,1);

63             id = key;

64             if(n==0) break;

65             if(p[id].d>0)

66             k = (k-1+p[id].d-1)%n+1;

67             else

68             k = ((k-1+p[id].d)%n+n)%n+1;

69         }

70         printf("%s %d\n",p[id].s,maxz);

71     }

72 }
View Code

 

你可能感兴趣的:(约瑟夫环)