POJ - 2886线段树+线性筛

Posted json-five

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ - 2886线段树+线性筛相关的知识,希望对你有一定的参考价值。

题意就是给你n个人,每个人有一个名字和A,如果A为正则向左找第A个,否则向右找第-A个,每找到一个就出列,然后第i个人出列的F(i)是i的所有因子个数

输出最大的F(i)和对应的名字

先用线性筛找出第几个出列的值最大maxn,那么求到maxn就可以了。

用线段树记录空位,k表示当前需要从剩余人第几个位置寻找,只要推出k,则转化为线段树的求位置的模型

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;
const int N=500010;
char name[N][15];
int pos[N];
int cnt[N];
struct node
{
    int l,r;
    int spare;
} seg[N<<2];

void pushup(int rt)
{
    seg[rt].spare=seg[2*rt].spare+seg[2*rt+1].spare;
}
void build(int rt,int L,int R)
{
    seg[rt].l=L;
    seg[rt].r=R;
    seg[rt].spare=1;
    if(L==R)
    {
        return;
    }
    int mid=(seg[rt].l+seg[rt].r)/2;
    build(2*rt,L,mid);
    build(2*rt+1,mid+1,R);
    pushup(rt);
}

int index;
void update(int rt,int val)
{
    if(seg[rt].l==seg[rt].r)
    {
        index = seg[rt].l;
        seg[rt].spare=0;
        return;
    }
    if(seg[2*rt].spare>=val)
        update(2*rt,val);
    else
        update(2*rt+1,val-seg[2*rt].spare);
    pushup(rt);
}
int slove(int n)//线性筛求最大
{
    int maxcnt=-0x3f3f3f3f;
    int maxn;
    memset(cnt,0,sizeof(cnt));
    for (int i=1; i<=n ; i++ )
    {
        cnt[i]++;
        for (int j=2*i; j<=n ; j+=i )
            cnt[j]++;
    }
    for (int i=1; i<=n ; i++ )
    {
        if(cnt[i]>maxcnt)
        {
            maxcnt=cnt[i];
            maxn=i;
        }
    }
    return maxn;
}
int main()
{
    int n,k;
    while(~scanf("%d%d",&n,&k))
    {
        int maxn=slove(n);
        for (int i=1; i<=n ; i++ )
        {
            scanf("%s %d",name[i],&pos[i]);
        }
        build(1,1,n);
        int mod=seg[1].spare;
        pos[0]=0;
        index=0;
        for (int i=1; i<=maxn; i++ )
        {
            if(pos[index]>0)
            {
                k=(k-1+pos[index]-1)%mod+1;
            }
            else
            {
                k=((k+pos[index]-1+mod)%mod+mod)%mod+1;
            }
            update(1,k);
            mod=seg[1].spare;
        }
        printf("%s %d
",name[index],cnt[maxn]);
    }
    return 0;
}

 

以上是关于POJ - 2886线段树+线性筛的主要内容,如果未能解决你的问题,请参考以下文章

POJ 2886 Who Gets the Most Candies? (线段树)

(线段树,反素数)poj2886-Who Gets the Most Candies?

POJ2886Who Gets the Most Candies?(线段树之约瑟夫)

POJ 2886 Who Gets the Most Candies? (线段树)

POJ-2886 Who Gets the Most Candies?---线段树+约瑟夫环

hdu 6287 口算训练(可持久化线段树+线性筛)