POJ 2886 Who Gets the Most Candies? 线段树
2012-08-13 21:58
351 查看
题意:几个人围成一个圈,第K个人开始出圈,k说出一个数(!=0)a,a>0表示左边的第a个人出列,a<0表示左边的d第a个人出列 ,直到最后一个人出圈
每个人出圈都有一个序号,如第一个出圈,第二个。。。找出所有序号中最大的反素数,反素数!!!找了一个表贴上了
这里讲的反素数 http://www.cnblogs.com/jackiesteed/articles/2018868.html
/article/6638749.html
(写的晕晕的,to me好不容易),其中找下一个位置的计算 假设位置是从 1~N,K为当前出圈的位置,该人说出的数是val ,首先N--(因为一个人出圈)
if(val>0) k=(k+val-2)%N+1,下一个相对于该人的位置是 K+val,但是该人出队以后,下一个就会前移一个位置,所以减一,然后位置1~N,还涉及到对N取余,(取余后0~N-1),所以括号里面减一,加在外面。相应的,if(val<0) k=((k+val-1)%N+N)%N+1; 跟poj 2828都属于查找吧
代码:
每个人出圈都有一个序号,如第一个出圈,第二个。。。找出所有序号中最大的反素数,反素数!!!找了一个表贴上了
这里讲的反素数 http://www.cnblogs.com/jackiesteed/articles/2018868.html
/article/6638749.html
(写的晕晕的,to me好不容易),其中找下一个位置的计算 假设位置是从 1~N,K为当前出圈的位置,该人说出的数是val ,首先N--(因为一个人出圈)
if(val>0) k=(k+val-2)%N+1,下一个相对于该人的位置是 K+val,但是该人出队以后,下一个就会前移一个位置,所以减一,然后位置1~N,还涉及到对N取余,(取余后0~N-1),所以括号里面减一,加在外面。相应的,if(val<0) k=((k+val-1)%N+N)%N+1; 跟poj 2828都属于查找吧
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #define nMAX 500005 using namespace std; struct Node { char name[12]; int val,num,l,r; }node[nMAX*4]; int n,k,cnt,dest,x; char ans[12]; int antiPrim[40]={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}, factor[40]={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}; void create(int l,int r,int u) { node[u].l=l,node[u].r=r; if(l==r) { scanf("%s%d",&node[u].name,&node[u].val); node[u].num=1; return ; } int mid=(r+l)/2; create(l,mid,2*u); create(mid+1,r,2*u+1); node[u].num=node[2*u].num+node[2*u+1].num; } void update(int u,int order) { node[u].num--; if(node[u].l==node[u].r) { if(order==antiPrim[dest]) { strcpy(ans,node[u].name); } else { n--; if(node[u].val>0){k=(k+node[u].val-1-1)%n+1;} else {k=((k+node[u].val-1)%n+n)%n+1;} } return ; } if(x<=node[2*u].num)update(2*u,order); else { x-=node[2*u].num; update(2*u+1,order); } } int main() { int i; while(~scanf("%d%d",&n,&k)) { create(1,n,1); for(i=0;i<35;i++) { if(n>=antiPrim[i]&&n<antiPrim[i+1]) dest=i; } int PP=n; for(i=1;i<=antiPrim[dest];i++)//进行antiPrim[dest]次就可以了 { x=k; update(1,i); } printf("%s %d\n",ans,factor[dest]); } return 0; }
相关文章推荐
- POJ 2886 Who Gets the Most Candies?(线段树)
- POJ 2886 Who Gets the Most Candies? (高合成数&用线段树维护约瑟夫环)
- POJ Who Gets the Most Candies? 2886(线段树)
- poj 2886 Who Gets the Most Candies?(线段树单点更新)
- POJ2886-Who Gets the Most Candies?-模拟约瑟夫环+反素数表(线段树上二分+爆搜打表)
- POJ 2886 Who Gets the Most Candies? (线段树)
- POJ 2886 Who Gets the Most Candies? (线段树)
- POJ 2886 Who Gets the Most Candies?(线段树模拟约瑟夫环,高合成数)
- POJ 2886 Who Gets the Most Candies? (打表+线段树)
- poj 2886 Who Gets the Most Candies?(线段树)
- poj 2886 Who Gets the Most Candies?(线段树、反素数)
- poj 2886 Who Gets the Most Candies?(线段树-单点更新)
- POJ 2886 Who Gets the Most Candies? (线段树 约瑟夫环问题变种)
- POJ 2886 Who Gets the Most Candies? [线段树-单点更新]【数据结构】
- POJ 2886 Who Gets the Most Candies?(线段树 + 约瑟夫环 + 反素数)
- (中等) POJ 2886 Who Gets the Most Candies? , 反素数+线段树。
- POJ-2886-Who Gets the MostCandies?-(线段树)
- POJ 2886 Who Gets the Most Candies?(线段树)
- POJ 2886 Who Gets the Most Candies? 线段树单点更新
- POJ 2886 Who Gets the Most Candies?【线段树单点更新+反素数打表】【好题】