POJ 2886 Who Gets the Most Candies? (线段树)

https://vjudge.net/problem/POJ-2886

题意:N个人围成一圈第一个人跳出圈后会告诉你下一个谁跳出来跳出来的人(如果他手上拿的数为正数,从他左边数A个,反之,从他右边数A个) 跳出来的人所得到的糖果数量和他跳出的顺序有关 所得的糖果数为 (假设他是第k个跳出的) 则他得到的糖数为k能被多少个数正数 比如说 k = 6 ;  6 = 1*2*3*6 所以他得到的糖数为4;

思路:线段数 先算出N个人中,是第几个人(id)跳出来得到的糖果最多。然后模拟id遍 长到第id个人的name
线段树的结点中保存该区间内还剩多少人,每次update 删除一个人。
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 
 5 using namespace std;
 6 
 7 #define L(rt) (rt<<1)
 8 #define R(rt) (rt<<1|1)
 9 
10 const int N=500010;
11 
12 int n,id;
13 
14 struct node{
15     int l,r,sum;    //sum 表 该区间剩余人数
16 }tree[N*3];
17 
18 struct date{
19     int val;
20     char name[15];
21 }boy[N];
22 
23 int ans[N]; //ans[i]保存第i个人跳出能得到的糖果数量
24 
25 void build(int l,int r,int rt){
26     tree[rt].l=l;
27     tree[rt].r=r;
28     tree[rt].sum=r-l+1;
29     if(l==r)
30         return ;
31     int mid=(l+r)>>1;
32     build(l,mid,L(rt));
33     build(mid+1,r,R(rt));
34 }
35 
36 int update(int key,int rt){
37     tree[rt].sum--;
38     if(tree[rt].l==tree[rt].r)
39         return tree[rt].l;
40     if(tree[L(rt)].sum>=key)
41         return update(key,L(rt));
42     else
43         return update(key-tree[L(rt)].sum,R(rt));
44 }
45 
46 void Solve(){   //计算ans
47     memset(ans,0,sizeof(ans));
48     for(int i=1;i<=n;i++){
49         ans[i]++;
50         for(int j=2*i;j<=n;j+=i)
51             ans[j]++;
52     }
53     int max=ans[1];
54     id=1;
55     for(int i=2;i<=n;i++)   //找出第几个人跳出获得的糖最多
56         if(ans[i]>max){
57             max=ans[i];
58             id=i;
59         }
60 }
61 
62 int main(){
63 
64     //freopen("input.txt","r",stdin);
65 
66     int i,k,mod;
67     while(~scanf("%d%d",&n,&k)){
68         Solve();
69         for(i=1;i<=n;i++)
70             scanf("%s%d",boy[i].name,&boy[i].val);
71         build(1,n,1);
72         mod=tree[1].sum;
73         int pos=0;
74         boy[0].val=0;
75         n=id;
76         while(n--){
77             if(boy[pos].val>0)  //k表剩余的人中从左起第k中出队
78                 k=((k-1+boy[pos].val-1)%mod+mod)%mod+1;
79             else
80                 k=((k-1+boy[pos].val)%mod+mod)%mod+1;
81             pos=update(k,1);
82             mod=tree[1].sum;
83         }
84         printf("%s %d
",boy[pos].name,ans[id]);
85     }
86     return 0;
87 }
原文地址:https://www.cnblogs.com/YingZhixin/p/7531575.html