您的位置:首页 > 其它

poj 2886 Who Gets the Most Candies?(线段树、反素数)

2014-07-02 13:27 477 查看
poj 2886 Who Gets the Most Candies?

此题线段树的思路倒是没什么问题,关键在于求1-N中约束个数最大那个数,当然如果知道反素数就没什么问题了,一开始不知道,打个表、、果断TLE

反素数详解

#include<stdio.h>
#include<string.h>
#include<math.h>
#define MAXN 500005
#define lch p<<1
#define rch p<<1|1
#define mid (t[p].l+t[p].r)>>1
int rprime[]={//反素数
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
};

int fact[]={//反素数约数个数
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
};
struct node
{
int l,r;
int sum;
}t[MAXN<<2];
void pushup(int p) {t[p].sum=t[lch].sum+t[rch].sum;}
void construct(int l,int r,int p)
{
t[p].l=l,t[p].r=r;
if(l==r)
{
t[p].sum=1;
return ;
}
int m=mid;
construct(l,m,lch);
construct(m+1,r,rch);
pushup(p);
}
void modify(int x,int p)
{
if(t[p].l==t[p].r)
{
t[p].sum=0;
return ;
}
int m=mid;
if(x<=m) modify(x,lch);
else modify(x,rch);
pushup(p);
}
int query(int x,int p)
{
if(t[p].l==t[p].r)
return t[p].l;
if(x<=t[lch].sum) return query(x,lch);
else return query(x-t[lch].sum,rch);
}
struct child
{
char name[12];
int num;
}c[MAXN];
int main()
{
int n,k;
while(scanf("%d%d",&n,&k)!=EOF)
{
construct(1,n,1);
for(int i=1;i<=n;i++)
scanf("%s%d",c[i].name,&c[i].num);
int ansi=0;
int i=0;
while(n>=rprime[i])
ansi=i++;
int cnt=0,pos=0;
while(n)
{
if(c[pos].num>0)
k=((k+c[pos].num-1)%n+n)%n;
else
k=((k+c[pos].num)%n+n)%n;
pos=query(k,1);
cnt++;
if(cnt==rprime[ansi])
{
printf("%s %d\n",c[pos].name,fact[ansi]);
break;
}
modify(pos,1);
n--;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  线段树 反素数