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. bootstrap真是个好东西

    之前就知道有bootstrap这么个东东,但是因为本身不做web,也就没有仔细了解.这次一个项目合作方使用django和bootstrap做的,有机会接触了一些,感觉确实非常好! 今天下午利用一个下午 ...

  2. Windows 8 关闭无线后无法打开WIFI的解决办法

    转:http://blog.sina.com.cn/s/blog_49d02ed101016b4n.html 在使用 Windows 8 的过程中,遇到过几次使用键盘上的功能键(笔者笔记本上的快捷键是 ...

  3. Android 国内镜像

    Android SDK官网国内很难直接访问,除了FQ/VPN等方法还是很不方便. 原有的Android SDK直接下载因http://dl-ssl.google.com/android/reposit ...

  4. BZOJ4195 [Noi2015]程序自动分析(离散化+并查集)

    4195: [Noi2015]程序自动分析 Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 689  Solved: 296 [Submit][Sta ...

  5. [转载]jQuery.extend 函数详解

    JQuery的extend扩展方法:      Jquery的扩展方法extend是我们在写插件的过程中常用的方法,该方法有一些重载原型,在此,我们一起去了解了解.      一.Jquery的扩展方 ...

  6. [转]使用Linux命令行测试网速

    装speedtest-cli speedtest-cli是一个用Python编写的轻量级Linux命令行工具,在Python2.4至3.4版本下均可运行.它基于Speedtest.net的基础架构来测 ...

  7. nyoj 32 组合数【简单dfs】

    组合数 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 找出从自然数1.2.... .n(0<n<10)中任取r(0<r<=n)个数的所有组合 ...

  8. c#基础语言编程-Path和Directory

    引言 在程序常会对文件操作,在对文件操作中需要对文件路径的进行定位,在.Net中针对寻找文件提供两个静态类以供调用,Path和Directory. Path类 来自命名空间SYstem.IO,Path ...

  9. Android中RelativeLayout的字符水平(垂直居中)对齐

    [背景] 此处Android中显示出来的TextView中的内容,水平中间不对其. 想要实现水平居中对齐. [折腾过程] 1.搜: android RelativeLayout horizontal ...

  10. [Redux] Supplying the Initial State

    We will learn how to start a Redux app with a previously persisted state, and how it merges with the ...