您的位置:首页 > 其它

POJ 2886 Who Gets the Most Candies? 线段树

2013-11-19 21:33 357 查看
题目: http://poj.org/problem?id=2886

左右转的果断晕,题目不难,关键是准确的转啊转。因为题目要求输出约数个数最多的数,所以预处理[1,500000]的约数的个数就行了。还有利用反素数的做法,太专业了,还是暴力预处理吧。。。

#include <stdio.h>
#include <string.h>
#include <math.h>

const int MAXN = 500010;

struct Tree_Node
{
int left, right, sum;
Tree_Node(){}
Tree_Node(int left, int right, int sum)
{
this->left = left;
this->right = right;
this->sum = sum;
}
}tree[MAXN<<2];

void build(int left, int right, int step)
{
tree[step] = Tree_Node(left, right, right-left+1);
if(tree[step].left == tree[step].right)
return;
int mid = left + (right-left) / 2;
build(left, mid, step<<1);
build(mid+1, right, step<<1|1);
}

int query(int num, int step)
{
tree[step].sum--;
if(tree[step].left == tree[step].right)
{
return tree[step].left;
}
if(num <= tree[step<<1].sum)
return query(num, step<<1);
else
return query(num - tree[step<<1].sum, step<<1|1);
}

int div[MAXN];
void cnt_divisible()
{
int x = sqrt(MAXN);
for(int i = 1; i <= x; i++)
{
int y = MAXN / i;
for(int j = i+1; j <= y; j++)
div[i*j] += 2;
div[i*i]++;
}
}

char name[MAXN][11];
int val[MAXN];
int main()
{
cnt_divisible();
int n, k;
while(scanf("%d %d", &n, &k) != EOF)
{
build(1, n, 1);
for(int i = 1; i <= n; i++)
scanf("%s %d", name[i], &val[i]);
int ans = 0, num = 0, cnt = 0;
while(n > 0)
{
n--;
int x = query(k, 1);
if(div[++cnt] > ans)
{
ans = div[cnt];
num = x;
}
if(n == 0)
break;
if(val[x] > 0)
k = (k + val[x] - 2) % n + 1;
else
k = ((k + val[x] - 1) % n + n) % n + 1;
}
printf("%s %d\n", name[num], ans);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: