码迷,mamicode.com
首页 > 其他好文 > 详细

POJ - 2886线段树+线性筛

时间:2018-10-21 16:54:05      阅读:104      评论:0      收藏:0      [点我收藏+]

标签:iostream   线性   eof   date   char   using   ++   记录   max   

题意就是给你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\n",name[index],cnt[maxn]);
    }
    return 0;
}

 

POJ - 2886线段树+线性筛

标签:iostream   线性   eof   date   char   using   ++   记录   max   

原文地址:https://www.cnblogs.com/Json-Five/p/9825413.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!