poj 2886 Who Gets the Most Candies? (树状数组+二分+反素数)

, Sempr知道了一种能把当前剩余人中某人的id和原始id关联起来的的方法。树状数组。sum(n)=i;就是原始位置为n的人目前在残存环形中位置是i。知道了有个反素数表。通过他第几个人出来时候糖果数最大。然后模拟出那个最大糖果数的人。#include<iostream>#include<sstream>#include<algorithm>#include<cstdio>#include<string.h>#include<cctype>#include<string>#include<cmath>#include<vector>#include<stack>#include<queue>#include<map>#include<set>using namespace std;const int INF=500003;int N,K;int bit[INF-3];char name [INF-2][16];int integer[INF-2];int a[39]= {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,500001};int b[39]= {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,1314521};int lowbit(int x){return x&(-x);}void add (int x,int val){++x;while(x<INF){bit[x]+=val;x+=lowbit(x);}}int sum(int x){int s = 0;while(x>0){s += bit[x];x-=lowbit(x);}return s;}int binary_Search(int id){int l,r,mid;int flag=1;l=0,r=N;while(r-l>1){mid = (l + r)>>1;if(sum(mid)<=id){l=mid;}else{r=mid;}}return l;}int main(){while(cin>>N>>K){–K;for(int i=0; i<N; i++){scanf("%s %d",name[i],&integer[i]);add(i,1);}int candy = -1,index;int iu = 0, Max = 0, p = 0;while (a[iu] <= N)iu++;p = a[iu-1];Max = b[iu-1];for(int i=1; i<p; i++){add(K,-1);int mod = N-i;int id=sum(K)+integer[K]+(integer[K]>0?-1:0);id=(id%mod+mod)%mod;K=binary_Search(id);}printf("%s %d\n",name[K],Max);}return 0;}

,年岁有加,并非垂老,理想丢弃,方堕暮年。

poj 2886 Who Gets the Most Candies? (树状数组+二分+反素数)

相关文章:

你感兴趣的文章:

标签云: