【POJ2886】【线段树】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 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
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?的更多相关文章
- POJ (线段树) Who Gets the Most Candies?
这道题综合性挺强的,又牵扯到数论,又有线段树. 线段树维护的信息就是区间中有多少个人没跳出去,然后计算出下一个人是剩下的人中第几个. 我在这调程序调了好久,就是那个模来模去的弄得我头晕. 不过题确实是 ...
- poj2886线段树(单点修改,区间查询)
Who Gets the Most Candies? Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 11955 Acc ...
- POJ-2886 Who Gets the Most Candies?---线段树+约瑟夫环
题目链接: https://cn.vjudge.net/problem/POJ-2886 题目大意: N个人围成一圈第一个人跳出圈后会告诉你下一个谁跳出来跳出来的人(如果他手上拿的数为正数,从他左边数 ...
- POJ-2886 Who Gets the Most Candies?(线段树+模拟)
题目大意:n个小孩按顺时针站成一圈,每次会有一个小孩出队(第一个出队的小孩已知),在他出队时会指定下一个出队的小孩,直到所有的小孩全部出队游戏结束.第p个出队的小孩会得到f(p)个糖果,f(p)为p的 ...
- POJ2886 Who Gets the Most Candies? 线段树 反素数
题意:有一群小朋友围成一个环,编号1,2,3…N.每个人手上握着一个非0的数字,首先第K个人出列,然后看他手上的数字,假设为m,则从下一个开始第m个人出列,一直如此.并设i为小于等于N的最大反素数,问 ...
- POJ 2886.Who Gets the Most Candies? -线段树(单点更新、类约瑟夫问题)
线段树可真有意思呢续集2... 区间成段的替换和增减,以及区间求和等,其中夹杂着一些神奇的操作,数据离散化,简单hash,区间异或,还需要带着脑子来写题. 有的题目对数据的操作并不是直接按照题面意思进 ...
- (中等) 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 ...
- poj2886(线段树求序列第k小)
题目链接:https://vjudge.net/problem/POJ-2886 题意:n个人围成一个圈,每个人有姓名s和权值val两个属性,第一轮序号为k的人退出,并根据其val指定下一个人,val ...
- POJ 2886 Who Gets the Most Candies?(线段树·约瑟夫环)
题意 n个人顺时针围成一圈玩约瑟夫游戏 每一个人手上有一个数val[i] 開始第k个人出队 若val[k] < 0 下一个出队的为在剩余的人中向右数 -val[k]个人 val[k ...
随机推荐
- 关于The APR based Apache Tomcat Native library警告
今天在Eclipse上配置Tomcat7,启动时看到如下警告信息: The APR based Apache Tomcat Native library which allows optimal pe ...
- lightoj 1021 - Painful Bases 状态压缩
题目链接:http://lightoj.com/volume_showproblem.php?problem=1021 #include<cstring> #include<cstd ...
- CentOS添加swap分区
在多个VPS上尝试. 1.进入目录 cd /var/ 2.获取要增加的SWAP文件块(这里以1GB为例) dd if=/dev/zero of=swapfile bs=1024 count=10383 ...
- Java GC专家系列2:Java 垃圾回收的监控
这是”成为GC专家系列”文章的第二篇.在第一篇理解Java垃圾回收中我们学习了几种不同的GC算法的处理过程,GC的工作方式,新生代与老年代的区别.到目前为止,你应该已经了解了JDK 7中的5种GC类型 ...
- 杭州(含嘉兴,绍兴,金华,湖州,义乌)Uber优步司机奖励政策(1月25日~1月31日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 正经学C#_变量与其转换:《c#入门经典》
上一节上了变量.末尾简单了说了下 命名方式,声明变量. 命名方式在C#,或者任何语言都是非常重要的一门学问.值得去深入思考一下.变量名的优化与其工作效率的提升,有很多大的关系的. 声明变量,上节介绍了 ...
- TCP/IP协议原理与应用笔记02:断点续传
1.断点续传简介: FTP(文件传输协议的简称)(File Transfer Protocol. FTP)客户端软件断点续传指的是在下载或上传时,将下载或上传任务(一个文件或一个压缩包)人 ...
- Java中ArrayList问题:删除一个ArrayList中的重复元素,注意留意一个问题
该问题有两种方法: 一 利用两个数组,此法简单,不讨论 二 利用一个数组,从第0个开始依次取元素,并在其后元素中查找是否有该元素,有则删掉后面的重复元素,依次遍历.---但是这种情况要特别注意,当后续 ...
- mac 终端常见指令
基本命令 1.列出文件 ls 参数 目录名 例: 看看驱动目录下有什么:ls /System/Library/Extensions参数 -w 显示中文,-l 详细信息, -a 包括隐藏文 ...
- Json字符串与字典互转
#pragma mark 转换json字符串 +(NSString *)toJSON:(id)aParam { NSData *jsonData=[NSJSONSerialization data ...