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
",p[id].s,maxz);
71     }
72 }
View Code
原文地址:https://www.cnblogs.com/shangyu/p/3184714.html