poj 2886 Who Gets the Most Candies?
2014-05-17 19:31
295 查看
题目
约瑟夫环,求第i个出去的名字是什么,i满足约数个数最大。
肯定会先想到预处理出50W以内所有数的约数,但这样TLE了,也不排除是我后面写戳了,讨论区里说打表打出反素数。假如a是一个反素数,b是>a的第一个反素数,那么[1,b-1]之间a的约数个数最多。
至于如何找到下一个出去的人,我采用的树状数组+二分。
约瑟夫环,求第i个出去的名字是什么,i满足约数个数最大。
肯定会先想到预处理出50W以内所有数的约数,但这样TLE了,也不排除是我后面写戳了,讨论区里说打表打出反素数。假如a是一个反素数,b是>a的第一个反素数,那么[1,b-1]之间a的约数个数最多。
至于如何找到下一个出去的人,我采用的树状数组+二分。
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define N 500005 #define clr(a) memset(a,0,sizeof(a)) int n,k; int c ,id,ans=0; int tmp; const int PV[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}; const int Nu[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}; bool vis ; struct Man{ char name[15]; int num; }a ; inline int lowbit(int t){ return t&(-t); } inline void add(int x,int val){ while(x<=n){ c[x]+=val; x+=lowbit(x); } } inline int sum(int x){ int ans=0; while(x>0){ ans+=c[x]; x-=lowbit(x); } return ans; } inline int bs(int s,int t,int val){ int m; int vv=0; if(s>1) vv=sum(s-1); while(s<=t){ m=(s+t)>>1; int v=sum(m)-vv; if(v==val && vis[m]==0) return m; if(v<val) s=m+1; else t=m-1; } } inline void Work(int now,int num){ vis[now]=1; if(num==id){ tmp=now; } if(num>=n) return; add(now,-1); if(a[now].num<0){ a[now].num*=-1; a[now].num%=(n-num); if(a[now].num==0) a[now].num=(n-num); int s=sum(now); if(s>=a[now].num){ int nxt=bs(1,now,s-a[now].num+1); Work(nxt,num+1); } else{ int ss=sum(n)-s-(a[now].num-s)+1; int nxt=bs(now,n,ss); Work(nxt,num+1); } } else{ a[now].num%=(n-num); if(a[now].num==0) a[now].num=(n-num); int s=sum(n)-sum(now); if(s>=a[now].num){ int nxt=bs(now,n,a[now].num); Work(nxt,num+1); } else{ int nxt=bs(1,now,a[now].num-s); Work(nxt,num+1); } } } int main(){ while(scanf("%d%d",&n,&k)!=EOF){ clr(c);clr(vis);ans=0; for(int i=1;i<=n;i++){ scanf("%s%d",a[i].name,&a[i].num); add(i,1); } int i=0; while(PV[i]<=n){ if(ans<Nu[i]){ ans=Nu[i]; id=PV[i]; } i++; } Work(k,1); printf("%s %d\n",a[tmp].name,ans); } return 0; }
相关文章推荐
- 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?
- 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?(线段树#3)
- 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?