您的位置:首页 > 其它

pku2886 Who Gets the Most Candies?

2008-11-08 02:47 246 查看
线段树解约瑟夫环,求第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,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 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;

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