poj 2868 Who Gets the Most Candies?
2014-05-13 19:24
267 查看
http://poj.org/problem?id=2886
题目大意:n 个小孩围城一圈,每个孩子手里都有一张卡片,卡片上面有一个整形数字,当第 k 个孩子离开圈子时,他手里卡片上的数字如果是个整数m, 下一个离开的就是 他左边第m 个孩子,如果是-m ,下一个离开的就是他右边的第m 个孩子。
第 x 个离开的孩子,他会得到糖果f(x)个,f(x) 是 x 的因子的个数,如f(4) = 3;要求得到最多糖果的孩子是谁,以及得到的糖果数。
其实就是求因子数最多的x ,这样我们就会想到,反素数。
反素数: 我们假设f(x) 是x 的因子数,对于所有的 1 <= i < x, 都有f(i) < f (x) ,此时我们就成 x 为反素数。 换句话说就是,所有小于x 的数的因子数都没有x 多。
题目大意:n 个小孩围城一圈,每个孩子手里都有一张卡片,卡片上面有一个整形数字,当第 k 个孩子离开圈子时,他手里卡片上的数字如果是个整数m, 下一个离开的就是 他左边第m 个孩子,如果是-m ,下一个离开的就是他右边的第m 个孩子。
第 x 个离开的孩子,他会得到糖果f(x)个,f(x) 是 x 的因子的个数,如f(4) = 3;要求得到最多糖果的孩子是谁,以及得到的糖果数。
其实就是求因子数最多的x ,这样我们就会想到,反素数。
反素数: 我们假设f(x) 是x 的因子数,对于所有的 1 <= i < x, 都有f(i) < f (x) ,此时我们就成 x 为反素数。 换句话说就是,所有小于x 的数的因子数都没有x 多。
#include<iostream> #include<algorithm> #include<cstdio> using namespace std; #define MAXN 500005 int RPrime[]= //反素数 { 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,55440,83160,110880,166320,221760,277200,332640,498960, 554400 }; int fact[]= //反素数约数个数 { 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,216 }; struct A { char s[15]; int num; }a[MAXN]; int n,k,sum[4*MAXN]; void pushup(int root) { sum[root] = sum[2*root] + sum[2*root+1]; } void build(int l,int r,int root) { if(l == r) { sum[root] = 1; return ; } int mid = (l+r)/2; build(l,mid,2*root); build(mid+1,r,2*root+1); pushup(root); } int update(int l ,int r,int root,int k) { sum[root]--; if(l == r) return l; int mid = (l+r)/2; if(k <= sum[2*root]) update(l,mid,2*root,k); else update(mid+1,r,2*root+1,k-sum[2*root]); } int main() { while(cin>>n>>k) { int i,p; for(i = 1; i <= n; i++) { scanf(" %s%d",a[i].s,&a[i].num); } i = 0; while(RPrime[i] <= n)//找到最大的反素数 { i++; } p = i-1; build(1,n,1); int tmp = 0;//tmp 表示当前位子 a[tmp].num = 0; for(i = 1; i <= RPrime[p]; i++) { int mod = sum[1];//mod 表示当前圈子中的全部人数 if(a[tmp].num > 0) k = ((k + a[tmp].num - 2)%mod + mod)%mod + 1;//k 表示第几个人要出去 else//因为k 是从1 开始的,为了避免k + a[tmp] == 0 的情况,所以要在后面+1,前面-1 k = ((k + a[tmp].num - 1)%mod + mod)%mod + 1; tmp = update(1,n,1,k);//tmp 表示第k 个出去的人的当前位子 } printf("%s %d\n",a[tmp].s,fact[p]); } }
相关文章推荐
- poj 2886 Who Gets the Most Candies?
- POJ Who Gets the Most Candies? 线段树 第 5天
- [POJ 2886] Who Gets the Most Candies? (Joseph环问题 + 树状数组)
- POJ 2886 Who Gets the Most Candies?
- POJ 2886 Who Gets the Most Candies?
- POJ 2886 Who Gets the Most Candies?(线段树)
- 【POJ 2886】Who Gets the Most Candies?
- POJ 2886 Who Gets the Most Candies? 已翻译
- poj2886——Who Gets the Most Candies?
- POJ-2886-Who Gets the MostCandies?-(线段树)
- POJ Who Gets the Most Candies? 2886(线段树)
- POJ - 2886 Who Gets the Most Candies? 树状数组 + 二分 + 反素数
- POJ 2886 Who Gets the Most Candies? [线段树-单点更新]【数据结构】
- POJ 2886 Who Gets the Most Candies?(反素数+线段树)
- [poj 2886] Who Gets the Most Candies[线段树][约瑟夫环][反素数]
- POJ-2886 Who Gets the Most Candies?
- POJ 2886 Who Gets the Most Candies?(线段树·约瑟夫环)
- POJ - 2886 Who Gets the Most Candies?(线段树)
- POJ 2886 Who Gets the Most Candies? 反素数+线段树
- poj 2886 Who Gets the Most Candies?(线段树单点更新模拟约瑟夫环)