poj 2886Who Gets the Most Candies?

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

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define maxn 500100
 5 using namespace std;
 6 
 7 typedef long long ll;
 8 const int prime[16]= {1,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
 9 int n,k;
10 struct node
11 {
12     int l,r,num;
13 } tree[maxn*3];
14 
15 ll maxsum,bestnum;
16 char name[maxn][110];
17 int a[maxn];
18 
19 void getantiprime(ll num, ll k,ll sum,int limit)
20 {
21      //num:当前枚举到的数,k:枚举到的第k大的质因子;sum:该数的约数个数;limit:质因子个数上限;
22     int i;
23     ll temp;
24     if(sum > maxsum)
25     {
26         maxsum = sum;
27         bestnum = num; //如果约数个数更多,将最优解更新为当前数;
28     }
29     if(sum==maxsum && bestnum > num)
30         bestnum = num; //如果约数个数相同,将最优解更新为较小的数;
31     if(k > 15)
32         return;
33     temp = num;
34     for(i=1; i<=limit; i++) //开始枚举每个质因子的个数;
35     {
36         if(temp*prime[k] > n)
37             break;
38         temp = temp * prime[k]; //累乘到当前数;
39         getantiprime(temp, k+1, sum*(i+1), i); //继续下一步搜索;
40     }
41 }
42 
43 void build(int i,int l,int r)//建树
44 {
45     tree[i].num=r-l+1;
46     tree[i].l=l;
47     tree[i].r=r;
48     if(l<r)
49     {
50         int mid=(l+r)/2;
51         build(i+i,l,mid);
52         build(i+i+1,mid+1,r);
53     }
54 }
55 
56 int search1(int num,int i)//查找原始序号
57 {
58     tree[i].num--;
59     if(tree[i].l==tree[i].r)
60     {
61         return tree[i].l;
62     }
63     if(num<=tree[i+i].num)
64         return search1(num,i+i);
65     return search1(num-tree[i+i].num,i+i+1);
66 }
67 
68 int main()
69 {
70     while(scanf("%d%d",&n,&k)!=EOF)
71     {
72         getantiprime(1,1,1,50);//找到n以内反素数最大的;
73         build(1,1,n);
74         for(int i=1; i<=n; i++)
75         {
76             scanf("%s %d",name[i],&a[i]);
77         }
78         int id;
79         for(int i=0; i<bestnum; i++)//约瑟夫原理
80         {
81             n--;
82             id=search1(k,1);
83             if(n==0) break;
84             if(a[id]>0)
85                 k=(k-1+a[id]-1)%n+1;
86             else
87                 k=((k-1+a[id])%n+n)%n+1;
88         }
89         printf("%s %lld
",name[id],maxsum);
90     }
91     return 0;
92 }
View Code
原文地址:https://www.cnblogs.com/fanminghui/p/3543969.html