POJ 2886

题目大意是说有n个人围成一圈,游戏的起点是k,每个人持有一个数字(非编号)num,每次当前的人退出圈,下一个人是他左边的第num个(也就是说下一个退出的是k+num, k可以为负数,表示右边的第num个),这里的num的范围是1e9, 现在一直如果一个人是第i个推出的,那么他的得分就是i的约束的个数,球得分最高的那个人的编号

这里有两个地方稍微不好处理:

1: num  < 1e9 这里只需要模拟一下就可以了,如果当前在k,往右走num,还剩下rest个人,那么下一步应该往右走num % rest,同时先使用线段树计算出当前位置的左侧和右侧还有多少人,线段树里保存的是当前区间还剩下多少个人,线段树就可以查找出下一个需要推出的人的编号

2:由于i的约数的个数是可以求出的,也就是说只需要在N内找到一个约束最大的数X,判断谁是第X个退出的就可以了。这里就用到了反素数的概念,设G[i]表示i的约数的个数,若对于任意的j,j<i有G[i] > G[j],那么i就是i反素数,这道题就转化为了球N以内的最大的反素数,设Max[i]为i以内的最大的反素数是Max[i]。在计算反素数时,设D[i]为i的约数的个数,由于对于i的一个素因子a,i除尽a后得到的a的幂是b,有D[i] = D[i/a] * (b+1) / b,而在计算D[i]时,D[i/a]已经被计算出,所以按照DP的思路,总体的复杂度就是NlonN(logN为求b时的复杂度)

 #include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define INF 1e9
#define inf (-((LL)1<<40))
#define lson k<<1, L, mid
#define rson k<<1|1, mid+1, R
#define mem0(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define mem(a, b) memset(a, b, sizeof(a))
#define FOPENIN(IN) freopen(IN, "r", stdin)
#define FOPENOUT(OUT) freopen(OUT, "w", stdout)
template<class T> T CMP_MIN(T a, T b) { return a < b; }
template<class T> T CMP_MAX(T a, T b) { return a > b; }
template<class T> T MAX(T a, T b) { return a > b ? a : b; }
template<class T> T MIN(T a, T b) { return a < b ? a : b; }
template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } typedef __int64 LL;
//typedef long long LL;
const int MAXN = ;
const int MAXM = ;
const double eps = 1e-;
const LL MOD = ; char name[MAXN][];
int N, K,cnt, l, r, curPos;
int num[MAXN], tree[MAXN<<], no[MAXN]; void buildTree(int k, int L, int R)
{
if(L == R) { tree[k] = ; return ; } int mid = (L + R) >> ; buildTree(lson); buildTree(rson); tree[k] = tree[k<<] + tree[k<<|];
} void update(int k, int L, int R, int x)
{
if(L == R) { tree[k] = ; no[L] = cnt; curPos = L; return ;} int mid = (L + R) >> ; if(x <= tree[k<<]) update(lson, x); else update(rson, x-tree[k<<]); tree[k] = tree[k<<] + tree[k<<|];
} int query(int k, int L, int R)
{
if(R < l || r < L) return ; if(l<=L && R<=r) return tree[k]; int mid = (L+R) >> ; return query(lson) + query(rson);
} void getNo()
{
cnt = ; int pos = K;
for(int j=;j<N-;j++)
{
update(, , N, pos);
l = ; r = curPos; int leftNum = query(, , N);
l = curPos; r = N; int rightNum = query(, , N);
int dis = abs(num[curPos]) % (N - cnt);
if(dis == ) dis = N - cnt;
if(num[curPos] > && rightNum >= dis) pos = leftNum + dis;
else if(num[curPos] > && rightNum < dis) pos = dis - rightNum;
else if(num[curPos] < && leftNum >= dis) pos = leftNum - dis + ;
else if(num[curPos] < && leftNum < dis) pos = *leftNum + rightNum - dis + ;
cnt ++;
}
for(int i=;i<=N;i++)if(!no[i]) no[i] = N;
} int isp[MAXN], yue[MAXN], D[MAXN], Max[MAXN];
void init()
{
mem1(isp);yue[] = ;
for(int i=;i<MAXN;i++) if(isp[i])
{
for(int j=*i;j<MAXN;j+=i)
{
isp[j] = ;
yue[j] = i;
}
}
D[] = Max[] = ;
for(int i=;i<MAXN;i++)
{
if(isp[i]) D[i] = ;
else
{
int last = i / yue[i];
int b = , n = i;
while(n % yue[i] == ) b ++, n /= yue[i];
D[i] = D[last] * (b+) / b;
}
if(D[i] > D[Max[i-]]) Max[i] = i;
else Max[i] = Max[i-];
}
} int main()
{
//FOPENIN("in.txt");
init();
while(~scanf("%d %d%*c", &N, &K))
{
mem0(tree); mem0(no);
buildTree(, , N);
for(int i=;i<=N;i++)
scanf("%s %d", name[i], &num[i]);
getNo();
for(int i=;i<=N;i++) if(no[i] == Max[N])
printf("%s %d\n", name[i], D[Max[N]]);
}
return ;
}

POJ 2886Who Gets the Most Candies?(线段树)的更多相关文章

  1. POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)

    POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...

  2. 【POJ 2777】 Count Color(线段树区间更新与查询)

    [POJ 2777] Count Color(线段树区间更新与查询) Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4094 ...

  3. 【POJ 2750】 Potted Flower(线段树套dp)

    [POJ 2750] Potted Flower(线段树套dp) Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4566   ...

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

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

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

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

  6. POJ 2886 Who Gets the Most Candies? 线段树。。还有方向感

    这道题不仅仅是在考察线段树,还他妹的在考察一个人的方向感.... 和线段树有关的那几个函数写了一遍就对了,连改都没改,一直在转圈的问题的出错.... 题意:从第K个同学开始,若K的数字为正 则往右转, ...

  7. poj 2528 Mayor's posters(线段树+离散化)

    /* poj 2528 Mayor's posters 线段树 + 离散化 离散化的理解: 给你一系列的正整数, 例如 1, 4 , 100, 1000000000, 如果利用线段树求解的话,很明显 ...

  8. poj 2155:Matrix(二维线段树,矩阵取反,好题)

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 17880   Accepted: 6709 Descripti ...

  9. POJ 2155 Matrix (二维线段树)

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 17226   Accepted: 6461 Descripti ...

随机推荐

  1. UVa 12325 Zombie's Treasure Chest【暴力】

    题意:和上次的cf的ZeptoLab的C一样,是紫书的例题7-11 不过在uva上交的时候,用%I64d交的话是wa,直接cout就好了 #include<iostream> #inclu ...

  2. XenServer6.2详细安装步骤

    系统要求 系统要求 XenServer 至少需要两台单独的 x86 物理计算机:一台用作 XenServer 主机,另一台用于运行XenCenter 应用程序. XenServer 主计算机完全专用于 ...

  3. HDU 5328 Problem Killer(水题)

    题意: 给一个序列,要找一个等差或等比的连续子序列,求其最长的长度. 思路: 扫两遍,判断等差或等比即可.从左往右扫,维护一个滑动窗口,考虑新加进来的数,如果满足了要求,则更新长度,否则只留最后两个数 ...

  4. (六) 6.1 Neurons Networks Representation

    面对复杂的非线性可分的样本是,使用浅层分类器如Logistic等需要对样本进行复杂的映射,使得样本在映射后的空间是线性可分的,但在原始空间,分类边界可能是复杂的曲线.比如下图的样本只是在2维情形下的示 ...

  5. 【英语】Bingo口语笔记(31) - Bring系列

    bring up 表示在哪长大 要用被动形式 BYOB 请自带酒瓶

  6. unity, sprite atlas

    一, Sprite Packer 可以直接在unity里放碎图,只要将Texture Type选为Sprite(2D and UI),Sprite Mode选为Single,再把想打在一张大图里的碎图 ...

  7. 可以用google了

    半年都上不了google,现在可以了, 哈哈,支持自动更新, 有时候用google还是很不错的,尤其是英文搜索.

  8. AE 中的查找与定位,以城市查找为例

    在文本框输入一个城市,在地图上查找,当找到后让mapcontrol自动跳转到地图上该点. IQueryFilter filter = new QueryFilterClass(); filter.Wh ...

  9. [整] Android Fragment 生命周期图

    1. onAttach ------called once the fragment is associated with its activity 2. onCreate-------called ...

  10. 【LeetCode】237 & 203 - Delete Node in a Linked List & Remove Linked List Elements

    237 - Delete Node in a Linked List Write a function to delete a node (except the tail) in a singly l ...