pku2886 Who Gets the Most Candies?

线段树解约瑟夫环,求第i个出圈的人

反素数打的是discuss里的表

 

 

#include <iostream>
#include 
<algorithm>
using namespace std;

#define MAXN 500001

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,166320221760277200332640498960554400665280};
const int factorNum[] = {1234689101216182024303236404860647280849096100108120128144160168180192200216224};


struct Node{
    
int l,r,c;
}nod[
3*MAXN];

int next[MAXN],n,k,kk;
char name[MAXN][12];

void buildtree(int u,int l,int r){
    nod[u].c
=r-l+1;
    nod[u].l
=l;
    nod[u].r
=r;
    
if(l==r)
        
return;
    buildtree(
2*u,l,(l+r)/2);
    buildtree(
2*u+1,(l+r)/2+1,r);
}


void insert(int u,int k){
    nod[u].c
--;
    
if(nod[u].l==nod[u].r){
        kk
=nod[u].l;
        
return;
    }
    
if(nod[2*u].c>=k)
        insert(
2*u,k);
    
else
        insert(
2*u+1,k-nod[2*u].c);
}

int query(int u,int l,int r){
    
if(l<=nod[u].l && nod[u].r<=r)
        
return nod[u].c;
    
int res=0;
    
if(l<=nod[2u].r)
        res
+=query(2*u,l,r);
    
if(r>=nod[2*u].l)
        res
+=query(2*u+1,l,r);
    
return res;
}




int main(){
    
int i,ith,tag,&nn=nod[1].c;
    
while(scanf("%d%d",&n,&k)!=EOF){
        
for(i=1;i<=n;i++)
            scanf(
"%s%d",&name[i],&next[i]);
        buildtree(
1,1,n);

        tag
=0;
        
while(antiprime[tag]<=n)//返回antiprime中小于等于n的最大反素数下标tag
            tag++;
        tag
--;
        ith
=antiprime[tag];//第ith个退出的人得到最多的糖

        
        kk
=0;
        next[kk]
=0;
        
while(ith--){
            
if(next[kk]>0)
                k
=((k+next[kk]-2)%nn+nn)%nn+1;
            
else
                k
=((k+next[kk]-1)%nn+nn)%nn+1;
            insert(
1,k);
        }
        printf(
"%s %d\n",name[kk],factorNum[tag]);
    

    }
    
return 0;
}

 

 

posted @ 2008-11-08 02:47  Beetlebum  阅读(475)  评论(0编辑  收藏  举报