您的位置:首页 > 其它

【POJ】2886 Who Gets the Most Candies?

2012-06-18 11:48 357 查看
#include<cstdio>
#define MAXN 500010
int n,k,ans,cnt;
int prime[]={2,3,5,7,11,13,17};
struct node
{
char name[12];
int val;
};
node p[MAXN];
int tree[MAXN<<2];
void AntiPrime(int res,int count,int index,int limit)
{
if(res<=n)
{
if(count>cnt)
{
cnt=count;
ans=res;
}
else if(count==cnt&&res<ans)
ans=res;
int i,temp;
for(i=temp=1;i<=limit;i++)
{
temp*=prime[index];
if(temp*res>n)
break;
else
AntiPrime(temp*res,count*(i+1),index+1,i);
}
}
}
inline void PushUp(int rt)
{
tree[rt]=tree[rt<<1]+tree[rt<<1|1];
}
void Build(int L,int R,int rt)
{
if(L==R)
tree[rt]=1;
else
{
int mid=(L+R)>>1;
Build(L,mid,rt<<1);
Build(mid+1,R,rt<<1|1);
PushUp(rt);
}
}
int Update(int x,int L,int R,int rt)
{
if(L==R)
{
tree[rt]=0;
return L;
}
int mid=(L+R)>>1,res;
if(tree[rt<<1]>=x)
res=Update(x,L,mid,rt<<1);
else
res=Update(x-tree[rt<<1],mid+1,R,rt<<1|1);
PushUp(rt);
return res;
}
int Query(int x,int y,int L,int R,int rt)
{
if(x<=L&&R<=y)
return tree[rt];
int mid=(L+R)>>1,res=0;
if(x<=mid)
res+=Query(x,y,L,mid,rt<<1);
if(y>mid)
res+=Query(x,y,mid+1,R,rt<<1|1);
return res;
}
int main()
{
int i,mov;
while(~scanf("%d%d",&n,&k))
{
for(ans=cnt=i=1;i<=n;i++)
scanf(" %s%d",p[i].name,&p[i].val);
AntiPrime(1,1,0,19);
Build(1,n,1);
k=Update(k,1,n,1);
for(i=1;i<ans;i++)
{
mov=Query(1,k,1,n,1);
if(p[k].val>0)
mov+=p[k].val;
else
mov+=p[k].val+1;
mov%=tree[1];
if(!mov)
mov=tree[1];
else if(mov<0)
mov+=tree[1];
k=Update(mov,1,n,1);
}
printf("%s %d\n",p[k].name,cnt);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: