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

来源:互联网 发布:淘宝衣服下架什么意思 编辑:程序博客网 时间:2024/05/16 08:31


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)>>1int 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;elsek=((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;}


0 0
原创粉丝点击