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. CSU 1507 超大型LED显示屏 第十届湖南省赛题

    题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1507 解题思路:这是一道模拟题,看了那么多人的代码,我觉得我的代码是最简的,哈哈,其实就 ...

  2. UVA 11021 Tribles(递推+概率)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=33059 [思路] 递推+概率. 设f[i]表示一只Tribble经 ...

  3. lightoj 1037 状态压缩

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1037 #include<cstdio> #include<cstri ...

  4. poj 1985 Cow Marathon【树的直径裸题】

    Cow Marathon Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 4185   Accepted: 2118 Case ...

  5. iOS高级工程师面试

    1. 你使用过Objective-C的运行时编程(Runtime Programming)么?如果使用过,你用它做了什么?你还能记得你所使用的相关的头文件或者某些方法的名称吗?  Objecitve- ...

  6. .Net设计模式_单列模式

    理解 博友的经典说法:很多人排队去厕所蹲坑一样,每一次只能让一个人去蹲坑,这是一种通俗的理解. 理论上的理解则为,我们需要写一个类,这个类的作用就是控制,从而保证在整个应用程序的生命周期中,在任何时刻 ...

  7. JAVA数据类型与DB2、Oracle、Sybase以及SQL Server对应关系

     java.sql.Types Java  IBM DB2  Oracle  Sybase  SQL-SERVER BIGINT java.lang.long  BIGINT  NUMBER (38, ...

  8. ListBoxControl 删除选择的项的方法

    public void RemoveSelectItems<T>(BaseListBoxControl listControl)        {            var list ...

  9. javascript正则表达式简述

    compile 编译或改变字符串,参数跟new RegExp相同 var patt = /man/g; var str = "man and woman"; str.replace ...

  10. jersey构建rest服务返回json数据

    1.  eclipse 创建 dynamic web project 2.  将jersey相关jar包放到libs目录下 3. web.xml 增加 jersey 相关内容 <?xml ver ...