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?

Input

There are several test cases in the input. Each test case starts with two integers N (0 < N ≤ 500,000) and K (1 ≤ KN) on the first line. The next N lines contains the names of the children (consisting of at most 10 letters) and the integers (non-zero with magnitudes within 108) on their cards in increasing order of the children’s numbers, a name and an integer separated by a single space in a line with no leading or trailing spaces.

Output

Output one line for each test case containing the name of the luckiest child and the number of candies he/she gets. If ties occur, always choose the child who jumps out of the circle first.

Sample Input

4 2
Tom 2
Jack 4
Mary -1
Sam 1

Sample Output

Sam 3

Source

【分析】

第二题.没什么好说的。

求素数用欧拉筛,dp求一下反素数。

然后注意一下细节,线段树直接上..其实树状数组也可以。

上一次使用树状数组做的,为什么我现在每个代码都有这么长?

 /*
唐代杜甫
《月夜忆舍弟》
戍鼓断人行,边秋一雁声。(边秋 一作:秋边)
露从今夜白,月是故乡明。
有弟皆分散,无家问死生。
寄书长不达,况乃未休兵。
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <utility>
#include <iomanip>
#include <string>
#include <cmath>
#include <queue>
#include <assert.h>
#include <map>
#include <ctime>
#include <cstdlib>
#include <stack>
#define LOCAL
const int MAXN = + ;
const int MAXM = + ;
const int INF = ;
const int SIZE = ;
const int maxnode = + ;
using namespace std;
int n, k, people;//people为真实人数
bool have[MAXN];
char str[MAXN][];
struct SEGTREE{
struct Node{
int sum, l, r;
int val;//代表权值
Node *ch[]; void update(){
if (l == r) return;
sum = ch[]->sum + ch[]->sum;
return;
}
}*root, mem[maxnode];
int tot;//静态数组 Node *NEW(int val){
Node *p = &mem[tot++];
p->val = val;
p->sum = ;
p->ch[] = p->ch[] = NULL;
return p;
}
void init(){
root = NULL;
tot = ;
build(root, , n);
/*change(root, 1);
change(root, 2);
printf("%d\n", find(root, 2));*/
}
void build(Node *&t, int l, int r){
if (t == NULL){
t = NEW(-);
t->l = l;
t->r = r;
}
if (l == r){scanf("%s", str[l]);scanf("%d", &t->val); return;}
int mid = (l + r)>>;
build(t->ch[], l, mid);
build(t->ch[], mid + , r);
t->update();
}
//将x位置的sum变为0
int change(Node *&t, int l){
if (t->l == l && t->r == l){
t->sum = ;
have[l] = ;//出圈
return t->val;
}
int mid = (t->l + t->r)>>;
int tmp;
if (l <= mid) tmp = change(t->ch[], l);
if (l > mid) tmp = change(t->ch[], l);
t->update();
return tmp;
}
//返回
int find(Node *&t, int l){//找到第l个人,pos记录他的位置
if (t->l == t->r) return t->l;
int c = t->ch[]->sum;
//if (l == (c + (have[t->ch[0]->r + 1] ^ 1))) return t->ch[0]->r + 1;
if (l <= c) return find(t->ch[], l);//左边,右边
else return find(t->ch[], l - c);
}
}A;
int prime[MAXN];
int Max[MAXN], num[MAXN];//num记录i的约束个数 void prepare(){
memset(prime, , sizeof(prime));//欧拉线性筛
prime[] = ;
for (int i = ; i <= ; i++){
if (!prime[i]) prime[prime[]++] = i;
for (int j = ; j < prime[]; j++){
if (prime[j] * i > ) break;
prime[i * prime[j]] = ;
if (i % prime[j] == ) break;
}
}
//DP+打表
num[] = ;
num[] = Max[] = ;
num[] = ;num[] = ;
num[] = ;num[] = ;
num[] = ;
num[] = ;
int Ans = ;
for (int i = ; i <= ; i++){
//printf("%d\n", num[Max[i - 1]]);
if (i >= ) {Max[i] = ;continue;}
if (i >= ) {Max[i] = ;continue;}
if (i >= ) {Max[i] = ;continue;}
if (i >= ) {Max[i] = ;continue;}
if (i >= ) {Max[i] = ;continue;}
if (i >= ) {Max[i] = ;continue;}
int cnt = , x = -, tmp = i;
for (int j = ; j <= (int)sqrt(1.0 * i); j++) if (i % j == ) {x = j;break;}
if (x == -) num[i] = ;//质数
else{
while (tmp % x == ) {tmp /= x; cnt++;}
cnt = (cnt + ) * num[tmp];
num[i] = cnt;
}
if (num[i] > num[Ans]) Ans = i;
Max[i] = Ans;
}
}
void init(){
memset(have, ,sizeof(have));//表示第i个人是否出圈
people = n;
A.init();
n = Max[n];//小于等于n的最大反素数
//找n个人出圈就行了
}
int MOD(int x, int t) {return x%t == ? t: x % t;}
void work(){
//if ( == 1)
int last = k;//表示上一个出圈人的名次
int t = A.change(A.root, k);//t为人手上的位置
//printf("%d", t);
for (int i = ; i <= n; i++){//i为现在正在要出圈的人是第i个
//计算现在出圈人的名次
int now;
if (t < ) now = MOD(MOD(last + t, people - (i - )) + (people - (i - )), (people - (i - )));
else now = MOD(MOD(last - + t, people - (i - )) + (people - (i - )), (people - (i - )));
int tmp = A.find(A.root, now);
if (i == n) {printf("%s %d\n", str[A.find(A.root, now)], num[n]);return;}
t = A.change(A.root, tmp);
last = now;
}
/*A.change(A.root, 1);
A.change(A.root, 2);
printf("%d", A.find(A.root, 1));*/
} int main(){ prepare();
while (scanf("%d%d", &n, &k) != EOF){
init();
work();
}
return ;
}

【POJ2886】【线段树】Who Gets the Most Candies?的更多相关文章

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

    这道题综合性挺强的,又牵扯到数论,又有线段树. 线段树维护的信息就是区间中有多少个人没跳出去,然后计算出下一个人是剩下的人中第几个. 我在这调程序调了好久,就是那个模来模去的弄得我头晕. 不过题确实是 ...

  2. poj2886线段树(单点修改,区间查询)

    Who Gets the Most Candies? Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 11955   Acc ...

  3. POJ-2886 Who Gets the Most Candies?---线段树+约瑟夫环

    题目链接: https://cn.vjudge.net/problem/POJ-2886 题目大意: N个人围成一圈第一个人跳出圈后会告诉你下一个谁跳出来跳出来的人(如果他手上拿的数为正数,从他左边数 ...

  4. POJ-2886 Who Gets the Most Candies?(线段树+模拟)

    题目大意:n个小孩按顺时针站成一圈,每次会有一个小孩出队(第一个出队的小孩已知),在他出队时会指定下一个出队的小孩,直到所有的小孩全部出队游戏结束.第p个出队的小孩会得到f(p)个糖果,f(p)为p的 ...

  5. POJ2886 Who Gets the Most Candies? 线段树 反素数

    题意:有一群小朋友围成一个环,编号1,2,3…N.每个人手上握着一个非0的数字,首先第K个人出列,然后看他手上的数字,假设为m,则从下一个开始第m个人出列,一直如此.并设i为小于等于N的最大反素数,问 ...

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

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

  7. (中等) 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 ...

  8. poj2886(线段树求序列第k小)

    题目链接:https://vjudge.net/problem/POJ-2886 题意:n个人围成一个圈,每个人有姓名s和权值val两个属性,第一轮序号为k的人退出,并根据其val指定下一个人,val ...

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

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

随机推荐

  1. (转载)函数:mysqli_query和mysql_query有何区别?

    (转载)http://wzan315.blog.163.com/blog/static/37192636201241732045299/ Mysqli.dll是一个允许以对象的方式或者过程操作数据库的 ...

  2. UILabel的使用方法

    UILabel 就是一个显示文字的控件,可以设置文字的各种属性. 构造方法:     //通过设置Label的边框来初始化UILabel     labelOfSlider = [[UILabelal ...

  3. 龙芯8089_D安装debian 8 iessie

    参考官方文档:https://wiki.debian.org/DebianYeeloong/HowTo/Install 下载网络引导文件后使用tftpd建立ftfp服务器,然后使用PMON tftp来 ...

  4. SRM 440(1-250pt, 1-500pt)

    DIV1 250pt 题意:小球从一段折线斜坡上滚下来,告诉所用时间,求重力加速度. 解法:二分答案模拟即可. tag:二分,simulation // BEGIN CUT HERE /* * Aut ...

  5. 武汉Uber优步司机奖励政策(1月25日~1月31日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  6. redis中各种数据类型对应的jedis操作命令

    redis中各种数据类型对应的jedis操作命令 一.常用数据类型简介: redis常用五种数据类型:string,hash,list,set,zset(sorted set). 1.String类型 ...

  7. SuperSocket使用demo

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using SuperSocket. ...

  8. oracle正则截取字符串的函数

    现在有这么一个需求, 数据库中的一个手输的'籍贯'字段,要按一定的规范截取显示在报表上,比如,如果'籍贯'的内容是:'山东省潍坊市昌乐县', 那么报表里要显示为:'山东昌乐', 如果'籍贯'是山东省潍 ...

  9. (转)Google Fonts 的介绍与使用

    转载自“前端笔记”  http://www.cnblogs.com/milly/archive/2013/05/10/google-fonts.html Google Fonts 是什么?(以下翻译为 ...

  10. Linq to Object实现分页获取数据

    最后调用的CSharp代码可以是: int totalcount = dboperator.Customers.Count(); //总记录数 int pagesize = 100;//每页显示数 / ...