关闭

poj 2886 线段树 单点更新

77人阅读 评论(0) 收藏 举报
分类:

题意:N个小孩围成一圈,玩约瑟夫环,每个小孩有一张卡片上面是数字a,正数代表右手边第a个小孩出队,负数表示左手边,游戏从第k个小孩开始,游戏直到所有小孩出队为止,第p个出队小孩得到f[p]分数,f[p]为p的因子数

题解:这里引入反素数的概念不清楚可以看http://blog.csdn.net/ACdreamers/article/details/25049767

每次询问只要从第一个出队的运行到当前给出的n范围内的最大反素数即可,然后和poj2828类似 线段树tree记录当前线段上有多少个人 然后主要就是数数的问题了 比较难理解http://blog.csdn.net/shiqi_614/article/details/6849406

#include<cstdio>
#include<cstring>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int N=500010;
int tree[N<<2];
const int antiprime[]={1,2,4,6,12,24,36,48,60,120,180,240,360,720,840,
                       1260,1680,2520,5040,7560,10080,15120,20160,25200,
                       27720,45360,50400,55440,83160,110880,166320,221760,
                       277200,332640,498960,554400,665280};//预处理反质数
const int factorNum[]={1,2,3,4,6,8,9,10,12,16,18,20,24,30,32,36,40,48,60,
                       64,72,80,84,90,96,100,108,120,128,144,160,168,180,
                       192,200,216,224};
struct child
{
    char name[15];
    int val;
}c[N];
void build(int l,int r,int rt)
{
    tree[rt]=r-l+1;
    if(l==r)return;
    int mid=(l+r)>>1;
    build(lson);build(rson);
}
int update(int p,int l,int r,int rt)
{
    tree[rt]--;
    if(l==r) return l;
    int mid=(l+r)>>1;
    if(p<=tree[rt<<1]) return update(p,lson);
    else return update(p-tree[rt<<1],rson);
}
int main()
{
    int i,n,k,&mod=tree[1];
    while(scanf("%d%d",&n,&k)!=EOF){
        for(i=1;i<=n;i++)scanf("%s%d",c[i].name,&c[i].val);
        build(1,n,1);
        int cnt=0;
        while(cnt<35&&antiprime[cnt]<=n)cnt++;
        cnt--;//求得该范围内的最大反质数factorNum[cnt]也即答案
        int pos=0;c[pos].val=0;//因为要取mod所以标号从0开始
        for(i=0;i<antiprime[cnt];i++){//只要玩到第答案个人也即最大值就行
            if(c[pos].val>0)k=((k+c[pos].val-2)%mod+mod)%mod+1;//之所以在减是因为现在的人离开了要从前面一个人开始数
            else k=((k+c[pos].val-1)%mod+mod)%mod+1;//标号从0开始所以要先-1再+1,和上面不同的是现在离开了答案就是对的
            pos=update(k,1,n,1);
        }
        printf("%s %d\n",c[pos].name,factorNum[cnt]);
    }
    return 0;
}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:27336次
    • 积分:1498
    • 等级:
    • 排名:千里之外
    • 原创:132篇
    • 转载:4篇
    • 译文:0篇
    • 评论:3条