Who Gets the Most Candies?----POJ_2886----线段树之单点更新
来源:互联网 发布:驱蚊草 知乎 编辑:程序博客网 时间:2024/05/29 19:30
题目地址:http://poj.org/problem?id=2886
/*Author:Bob Lee2012.9.26=====================================================================题目:N 个小孩围成一圈,他们被顺时针编号为 1 到 N。每个小孩手中有一个卡片,上面有一个非 0 的数字,游戏从第 K 个小孩开始,他告诉其他小孩他卡片上的数字并离开这个圈,他卡片上的数字 A 表明了下一个离开的小孩,如果 A 是大于 0 的,则下个离开的是左手边第 A 个,如果是小于 0 的,则是右手边的第 -A 个小孩。游戏将直到所有小孩都离开,在游戏中,第 p 个离开的小孩将得到 F(p) 个糖果,F(p) 是 p 的约数的个数,问谁将得到最多的糖果。输出最幸运的小孩的名字和他可以得到的糖果。=====================================================================思路:反素数:对 x来说约束个数 G(x),如果 对于 i<x 有 G(i)<G(x)则称x为反素数。那么这个题目里面就是要求出最大的反素数这个是可以打表的,但是我们不知道到底是谁在这个数出去的我们就需要用到模拟另外,我们要引进一个初始值0第0个孩子的num也为0方便我们后面的操作对于num>0,是它后面的,由于它本身也要已经是要删掉了的,所以k = k+num-1elsek = k+num*/#include<cstdio>#include<iostream>#include<cstring>#include<string>using namespace std;#define maxn 500005#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1int sum[maxn<<2];int lastpos;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 c{ char name[20]; int num;}child[maxn];void PushUp(int rt){ sum[rt] = sum[rt<<1]+sum[rt<<1|1];}void build(int l,int r,int rt){ if(l == r) { sum[rt] = 1; return; } int m = (l+r)>>1; build(lson); build(rson); PushUp(rt);}void update(int p,int l,int r,int rt){ sum[rt]--; if(l == r) { lastpos = l; return; } int m = (l+r)>>1; if(p <= sum[rt<<1]) update(p,lson); else update(p-sum[rt<<1],rson);}int main(){ int n,k; while(~scanf("%d%d",&n,&k)) { //PS:用scanf和printf要快得多,不然超时 for(int i=1;i<=n;i++) { scanf("%s%d",child[i].name,&child[i].num); } build(1,n,1); int P=0; //找出<=n的最大反素数 for(int i=0;RPrime[i] <= n;i++) { P = i; } int low=1; int high = RPrime[P]; lastpos = 0; child[lastpos].num = 0; /* 我们已经知道<=n的最大反素数high 现在我们就是要模拟到底谁是第high个出去的 每次出去一个 用线段树来保存这个区间还有多少人 */ while(low++<=high) { int mod = sum[1]; //下面这两个k的循环公式,是自己在草稿纸上演算一下就可以推出来 if(child[lastpos].num > 0) k = ((k+child[lastpos].num-2)%mod+mod)%mod + 1; else k = ((k+child[lastpos].num-1)%mod+mod)%mod + 1; update(k,1,n,1); } printf("%s %d",child[lastpos].name,fact[P]); }}
- Who Gets the Most Candies?----POJ_2886----线段树之单点更新
- POJ2886:Who Gets the Most Candies?(线段树单点更新)
- 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 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 Most Candies? 【线段树单点更新 + 反素数】
- POJ 2886 Who Gets the Most Candies? [线段树-单点更新]【数据结构】
- POJ 2886 Who Gets the Most Candies? 线段树单点更新
- Who Gets the Most Candies? 线段树
- poj2886Who Gets the Most Candies?【线段树单点更新】
- POJ 2886 Who Gets the Most Candies?(单点更新)
- 报表的设计
- Hibernate 可以实现分页查询
- ZOJ 3464 Rugby Football 水题
- ZOJ 3465 The Hive 暴力模拟
- 为激发应用开发商兴趣,鲍尔默展示自用Surface
- Who Gets the Most Candies?----POJ_2886----线段树之单点更新
- 使用 HibernateTemplate 实现分页查询
- Spring Hibernate 模板实现分页
- linux 学习笔记二
- HTML5新标签语义及用法
- c++学习笔记-文本查询程序
- 传统软件向SaaS软件转型方案的研究
- Java类型转换
- 游戏设计中常用的设计模式