Description

  N children are sitting in a circle to play a game.

  The children are numbered from 1 to N in clockwise order. Each of them has a card with a non-zero integer on it in his/her hand. The game starts from the K-th child, who tells all the others the integer on his card and jumps out of the circle. The integer on his card tells the next child to jump out. Let A denote the integer. If A is positive, the next child will be the A-th child to the left. If A is negative, the next child will be the (−A)-th child to the right.

  The game lasts until all children have jumped out of the circle. During the game, the p-th child jumping out will get F(p) candies where F(p) is the number of positive integers that perfectly divide p. Who gets the most candies?

  题意大致等同于约瑟夫环的问题,一次出来一个,然后出来x个人,其中x表示约数个数最多的数中最小的那个。

  做这个题时还不知道什么是反素数,用最笨的方法 (用了3s+时间) 打出了表,直接复制上的。然后就是构建线段树了,这个的线段树不难构建,就是记录区间内还没出去的人的个数。然后更新的话是标记某个点为出去了,并且返回这个点的位置,作为下一次计数的起点。询问的话就是某个区间的没出去的个数。

  反素数的话也在学习中,推荐ACdreamer的文章:http://blog.csdn.net/ACdreamers/article/details/25049767

代码如下:(注:写的比较乱,水平有限。)

#include<iostream>
#include<cstdio> using namespace std; const int remMax[][]={
{,},{,},{,},{,},{,},
{,},{,},{,},{,},
{,},{,},{,},{,},
{,},{,},{,},{,},
{,},{,},{,},{,},
{,},{,},{,},{,},
{,},{,},{,},{,},
{,},{,},{,},{,},
{,},{,},{,}}; int N,K;
char name[][];
int number[];
int BIT[*]; int findM(int x)
{
for(int i=;i<;++i)
if(remMax[i][]<=x&&remMax[i+][]>x)
return i;
} void pushUP(int po)
{
BIT[po]=BIT[po*]+BIT[po*+];
} void build_tree(int L,int R,int po)
{
BIT[po]=(R-L+); if(R==L) return; int M=(L+R)/;
build_tree(L,M,po*);
build_tree(M+,R,po*+);
} int query(int ql,int qr,int L,int R,int po)
{
if(ql>qr)
return ; if(ql<=L&&qr>=R)
return BIT[po]; int M=(L+R)/;
int temp=; if(ql<=M)
temp+=query(ql,qr,L,M,po*);
if(qr>M)
temp+=query(ql,qr,M+,R,po*+); return temp;
} int update(int un,int L,int R,int po)
{
--BIT[po]; if(L==R)
return L; int M=(L+R)/; if(BIT[po*]>=un)
return update(un,L,M,po*);
else
return update(un-BIT[po*],M+,R,po*+);
} int main()
{
int temp,temp1;
int n,las;
int times,fp; while(~scanf("%d %d",&N,&K))
{
for(int i=;i<=N;++i)
scanf("%s %d",name[i],&number[i]); build_tree(,N,); temp=findM(N);
times=remMax[temp][];
fp=remMax[temp][]; las=; for(int i=;i<=times;++i)
{
if(K>)
{
K%=(N-i+);
if(K==)
K=N-i+;
}
else
{
K%=(N-i+);
if(K==)
K=;
else
K=(N-i+)+K;
} temp1=query(las+,N,,N,); if(temp1>=K)
K=(N-i+)-(temp1-K);
else
K=(K-temp1); temp1=update(K,,N,); las=temp1;
K=number[las];
} printf("%s %d\n",name[las],fp);
} return ;
}

(中等) POJ 2886 Who Gets the Most Candies? , 反素数+线段树。的更多相关文章

  1. POJ 2886 Who Gets the Most Candies?(反素数+线段树)

    点我看题目 题意 :n个小盆友从1到n编号按顺时针编号,然后从第k个开始出圈,他出去之后如果他手里的牌是x,如果x是正数,那下一个出圈的左手第x个,如果x是负数,那出圈的是右手第-x个,游戏中第p个离 ...

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

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

  3. poj 2886 Who Gets the Most Candies?(线段树和反素数)

    题目:http://poj.org/problem?id=2886 题意:N个孩子顺时针坐成一个圆圈且从1到N编号,每个孩子手中有一张标有非零整数的卡片. 第K个孩子先出圈,如果他手中卡片上的数字A大 ...

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

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

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

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

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

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

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

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

  8. POJ 2886 Who Gets the Most Candies?

    思路: 对于 k 位置的 孩子,他的 数字是 +num 那么因为他自己本身是要被踢走的,所以相对位置 为k= k+num-1 如果数字是 -num,那么按正着数就没影响,k=k-num.线段树存储当前 ...

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

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

随机推荐

  1. oracle多种导入导出数据方法

    dmp格式: 1.dmp格式的导出可以通过客户端工具(PL/SQL)操作来完成,通过菜单栏---->Tools---->Export Tables,然后设置勾选相应参数即可,rows代表是 ...

  2. Linux试题及答案

    一. 单选题: 1.添加一条静态路由,使到网络196.199.3通过eth2接口出去,用: A. route add -net 196.199.3.0 B. route add -net 196.19 ...

  3. keepalived: Compile & startup

    first get keepalived source from git: git clone https://github.com/acassen/keepalived then unzip and ...

  4. [转]动态添加Fragments

    本章节翻译自<Beginning-Android-4-Application-Development>,如有翻译不当的地方,敬请指出. 原书购买地址http://www.amazon.co ...

  5. android笔记20170116

    封装http请求类,利用回调机制获取返回值 public interface HttpCallbackListener { void onFinish(String response); void o ...

  6. cc2530-----串口透明传输分析

    Zigbee协议栈学习之串口透明传输实验(SerialApp)流程分析   第一个功能:协调器的组网,终端设备和路由设备发现网络以及加入网络 //第一步:Z-Stack 由 main()函数开始执行, ...

  7. java 线程的同步

    Example12_7.java public class Example12_7 { public static void main(String args[]) { Bank bank = new ...

  8. java 数据流

    Example10_11.java import java.io.*; public class Example10_11 { public static void main(String args[ ...

  9. FZU 2086 餐厅点餐(枚举)

    ///个人感觉vector好看一点 #include<iostream> #include<cstdio> #include<cstring> #include&l ...

  10. ffmpeg合并多个视频

    实例1: 把4个视频(1.f4v, 2.f4v, 3.f4v, 4.f4v)合并成一个文件(out.mp4) 基本无损,而且速度飞快! #-vcodec copy -acodec copy   == ...