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

#include<iostream>
#include<cstdio>
#include<cstring>
#include<math.h>
#include<algorithm>
using namespace std;

const int INF=0x3f3f3f3f;
const int maxn=500010;
int T,n,k;
int a[maxn],loc;
char name[maxn][15];

int antiPrime[]={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 factorNum[]={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 segmentTree{
	int l;
	int r;
	int v;
}node[3*maxn];

void build(int rt,int l,int r){
	node[rt].l=l;
	node[rt].r=r;
	node[rt].v=r-l+1;
	if(l==r) return ;
	int mid=(l+r)>>1;
	build(rt<<1,l,mid);
	build(rt<<1|1,mid+1,r);
}

void Update(int rt,int pos){
	node[rt].v--;
	if(node[rt].l==node[rt].r){
		loc=node[rt].r;
		return ;
	}
	if(pos<=node[rt<<1].v)
		Update(rt<<1,pos);
	else
		Update(rt<<1|1,pos-node[rt<<1].v);
}

int main(){
#ifndef ONLINE_JUDGE
	freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);
#endif
	while(~scanf("%d%d",&n,&k)){
		build(1,1,n);
		for(int i=1;i<=n;i++){
			scanf("%s%d",name[i],&a[i]);
		}
		int i=0;
		while(antiPrime[i]<=n)
			i++;
		int ansNum=factorNum[i-1];
		int p=antiPrime[i-1];
		while(p--){
			n--;
			Update(1,k);
			if(!n) break;
			if(a[loc]>=0)
				k=(k+a[loc]-2)%n+1;
			else
				k=((k+a[loc]-1)%n+n)%n+1;
		}
		printf("%s %d\n",name[loc],ansNum);
	}
	return 0;
}



附上打表代码:

memset(f,0,sizeof(f));
for(int i=1;i<maxn;i++){
	for(int j=0;j<maxn;j+=i){
		f[j]++;
	}
}
int max=0;
for(int i=1;i<maxn;i++){
	if(f[i]>max){
		max=f[i];
		//cout<<i<<",";
		cout<<f[i]<<",";
	}
}


你可能感兴趣的:(poj 2886 Who Gets the Most Candies?(线段树+反素数))