题意:一堆小朋友围成一个圈,规定从k开始玩,每个被选中的人都有一个数字,正数代表从他左边开始数num,负数从右边数,被选中的人继续按照上述操作,直到都退出圈子,第i个退圈的人能拿到一个点数,这个点数是i的因数个数(比如第4个人拿3点)。问:谁点数最多,一样多选第一个。

思路:一道好题啊,万万没想到是线段树,想要想到感觉还是有点难度的。这道题其实就是要一直维护剩余人数,但是以前没做过线段树维护剩余人数的,一时半会想不到...首先,我们要用打表找到所有点数。然后用线段树维护剩余人数,这里有一个剩余人数位置和所有人数位置转换的过程,是用线段树解决的。线段树的每个节点储存的是某个区间的剩余人数,所以我们在用一个人在剩余人中的位置找到他的编号时,是比较sum节点而非L,R。还有向左向右方向要注意,画个圈慢慢感受。具体看注释。

代码:

#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#define ll long long
const int maxn = 500000+5;
const int MOD = 1e7;
const int INF = 0x3f3f3f3f;
using namespace std;
struct node{
char name[12];
int num;
}e[maxn];
int get[maxn],sum[maxn << 2];
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(l,m,rt << 1);
build(m + 1,r,rt << 1 | 1);
pushup(rt);
}
int update(int pos,int l,int r,int rt){
if(l == r){
sum[rt] = 0;
return l;
}
int ans;
int m = (l + r) >> 1;
if(pos <= sum[rt << 1]) //pos代表在剩余人数中的第几个,所以写法略有不同
ans = update(pos,l,m,rt << 1);
else
ans = update(pos - sum[rt << 1],m + 1,r,rt << 1 | 1);
pushup(rt);
return ans;
}
void init(){
int top = 500000;
memset(get,0,sizeof(get));
for(int i = 1;i <= top;i++){
get[i]++;
for(int j = 2*i;j <= top;j += i){
get[j]++;
}
}
}
int main(){
init();
int n,k;
while(~scanf("%d%d",&n,&k)){
build(1,n,1);
for(int i = 1;i <= n;i++)
scanf("%s%d",e[i].name,&e[i].num);
int aim = 0,MAX = -1;
for(int i = 1;i <= n;i++){
if(get[i] > MAX){
aim = i;
MAX = get[i];
}
}
int pos; //开始计算的位置
int mov,all,now = 0;
while(true){
pos = update(k,1,n,1); //被宰的是哪个人
now++;
if(now == aim) break;
mov = e[pos].num;
if(mov > 0){ //在左边
k = (k - 1 + mov - 1)%sum[1] + 1; //这里的pos是剩余人中的编号
//第一个-1是因为pos这个人已经被宰了,所以他这个位置其实是没有的
//第二个-1是防止%之后归0,所以先-1再+1
}
else{ //在右边
k = ((k - 1 + mov)%sum[1] + sum[1])%sum[1] + 1;
}
}
printf("%s %d\n",e[pos].name,MAX);
}
return 0;
}

POJ 2886 Who Gets the Most Candies? (线段树)题解的更多相关文章

  1. POJ 2886.Who Gets the Most Candies? -线段树(单点更新、类约瑟夫问题)

    线段树可真有意思呢续集2... 区间成段的替换和增减,以及区间求和等,其中夹杂着一些神奇的操作,数据离散化,简单hash,区间异或,还需要带着脑子来写题. 有的题目对数据的操作并不是直接按照题面意思进 ...

  2. POJ 2886 Who Gets the Most Candies?(线段树&#183;约瑟夫环)

    题意  n个人顺时针围成一圈玩约瑟夫游戏  每一个人手上有一个数val[i]   開始第k个人出队  若val[k] < 0 下一个出队的为在剩余的人中向右数 -val[k]个人   val[k ...

  3. POJ 2886 Who Gets the Most Candies? 线段树。。还有方向感

    这道题不仅仅是在考察线段树,还他妹的在考察一个人的方向感.... 和线段树有关的那几个函数写了一遍就对了,连改都没改,一直在转圈的问题的出错.... 题意:从第K个同学开始,若K的数字为正 则往右转, ...

  4. POJ 2886 Who Gets the Most Candies? 线段树

    题目: http://poj.org/problem?id=2886 左右转的果断晕,题目不难,关键是准确的转啊转.因为题目要求输出约数个数最多的数,所以预处理[1,500000]的约数的个数就行了. ...

  5. poj 2886 "Who Gets The Most Candies?"(树状数组)

    传送门 参考资料: [1]:http://www.hankcs.com/program/algorithm/poj-2886-who-gets-the-most-candies.html 题意: 抢糖 ...

  6. poj 3468 A Simple Problem with Integers 线段树 题解《挑战程序设计竞赛》

    地址 http://poj.org/problem?id=3468 线段树模板 要背下此模板 线段树 #include <iostream> #include <vector> ...

  7. 线段树(单点更新) POJ 2886 Who Gets the Most Candies?

    题目传送门 #include <cstdio> #include <cstring> #define lson l, m, rt << 1 #define rson ...

  8. POJ 2828 Buy Tickets(排队问题,线段树应用)

    POJ 2828 Buy Tickets(排队问题,线段树应用) ACM 题目地址:POJ 2828 Buy Tickets 题意:  排队买票时候插队.  给出一些数对,分别代表某个人的想要插入的位 ...

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

    [题目链接] http://poj.org/problem?id=2886 [题目大意] 一些人站成一个圈,每个人手上都有一个数字, 指定从一个人开始淘汰,每次一个人淘汰时,将手心里写着的数字x展示 ...

  10. (中等) POJ 2886 Who Gets the Most Candies? , 反素数+线段树。

    Description N children are sitting in a circle to play a game. The children are numbered from 1 to N ...

随机推荐

  1. POJ2286 The Rotation Game[IDA*迭代加深搜索]

    The Rotation Game Time Limit: 15000MS   Memory Limit: 150000K Total Submissions: 6325   Accepted: 21 ...

  2. onethink封装arclist调用文章列表!

    其实没有什么东西,做个记录,方便以后使用! <ul> <arclist mid='2' cid='2' row='2'> <li>{$title}</li&g ...

  3. html 标准属性不要用 setAttribute 方法

    html 中有些属性,譬如 checked , autofocus 只要存在就会有效,即使值是 false ,譬如: <input autofocus=false id='test'> & ...

  4. 使用MySQLMTOP监控MySQL性能(一)

    一.环境说明 1.服务器角色 服务器角色 172.18.35.29 10.160.22.14 (MySQL Master) 10.160.22.47 (MySQL Slave) 监控点 YES NO ...

  5. Nexus私有仓库简介

    1.    Nexus中的仓库 1.1  类型介绍 登陆Nexus,在左边菜单栏里选择Repositories,然后会出现右边的画面,右边上半部分是列出来的repository,黑体字是类型为grou ...

  6. SIFT算法的教程及源码

    1.ubc:DAVID LOWE---SIFT算法的创始人,两篇巨经典经典的文章http://www.cs.ubc.ca/~lowe/[1] 2.cmu:YanKe---PCASIFT,总结的SIFT ...

  7. New Garbage Collector http://wiki.luajit.org/New-Garbage-Collector

    New Garbage Collector http://wiki.luajit.org/New-Garbage-Collector GC Algorithms This is a short ove ...

  8. Java Naming and Directory Interface (JNDI) Java 命名和目录接口

    https://www.oracle.com/technetwork/java/jndi/index.html Lesson: Overview of JNDI (The Java™ Tutorial ...

  9. jQuery 的attr()方法

    在JS中设置节点的属性与属性值用到setAttribute(),获得节点的属性与属性值用到getAttribute(),而在jquery中,用一个attr()就可以全部搞定了,赞一个先 ^^ jque ...

  10. 修改hosts搭建本地站点

    想要搭建本地站点.例如想要将www.nbb.com映射到本地服务器,而不是网络的.需要修改hosts文件 1 打开hosts所在目录  C:\Windows\System32\drivers\etc ...