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. HDOJ/HDU 2549 壮志难酬(取小数点后几位~)

    Problem Description 话说MCA山上各路豪杰均出山抗敌,去年曾在江湖威名显赫的,江湖人称<万军中取上将首级舍我其谁>的甘露也不甘示弱,"天将降大任于斯人也,必先 ...

  2. bzoj 1923 [Sdoi2010]外星千足虫(高斯消元+bitset)

    1923: [Sdoi2010]外星千足虫 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 634  Solved: 397[Submit][Status ...

  3. JavaScript高级程序设计1.pdf

    第一遍通读的时候对JavaScript一点都不了解翻了一整本书仅仅是眼熟的几个名词,现在会写一些js效果了,对程序有一定的认知,又要在读一遍,再加深一些了解,当然以后还会有第三遍第四遍,等完全啃透了这 ...

  4. GPG error: the public key is not available

    GPG error: The following signatures couldn't be verified because the public key is not available I h ...

  5. App被拒绝的原因收录

    转自:dApps开发者 » APP被苹果App Store拒绝的79个原因(未完待续) 1.程序有重大bug,程序不能启动,或者中途退出.2.绕过苹果的付费渠道,我们之前游戏里的用兑换码兑换金币.3. ...

  6. OpenStack Havana 部署在Ubuntu 12.04 Server 【OVS+GRE】(二)——网络节点的安装

    序:OpenStack Havana 部署在Ubuntu 12.04 Server [OVS+GRE] 网络节点: 1.安装前更新系统 安装好ubuntu 12.04 Server 64bits后,进 ...

  7. HDU2037 今年暑假不AC 贪心算法

    贪心算法 : 贪心算法就是只考虑眼前最优解而忽略整体的算法, 它所做出的仅是在某种意义上的局部最优解, 然后通过迭代的方法相继求出整体最优解. 但是不是所有问题都可以得到整体最优解, 所以选择贪心策略 ...

  8. 局域网内linux由ip反解析主机名

  9. 3 kafka介绍

     本博文的主要内容有 .kafka的官网介绍 http://kafka.apache.org/ 来,用官网上的教程,快速入门. http://kafka.apache.org/documentatio ...

  10. list,set,map,数组间的相互转换

    1.list转set Set set =  new  HashSet( new  ArrayList()); 2.set转list List list =  new  ArrayList( new   ...