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

题目链接

注意题目中给的顺序是顺时针的,所以在数组中应该是倒着存的。左就是顺时针,右就是逆时针。各种调试之后,终于A了,很多种情况考虑情况。

  1 #include <cstring>
  2 #include <cstdio>
  3 #include <string>
  4 #include <iostream>
  5 #include <algorithm>
  6 #include <vector>
  7 using namespace std;
  8 char name[500001][11];
  9 int o[500001];
 10 int p[500001];
 11 int s[500001];
 12 int n;
 13 int lowbit(int t)
 14 {
 15     return t&(-t);
 16 }
 17 void insert(int t,int d)
 18 {
 19     while(t <= n)
 20     {
 21         p[t] += d;
 22         t += lowbit(t);
 23     }
 24 }
 25 int getsum(int t)
 26 {
 27     int sum = 0;
 28     while(t > 0)
 29     {
 30         sum += p[t];
 31         t -= lowbit(t);
 32     }
 33     return sum;
 34 }
 35 int find(int x)
 36 {
 37     int str,mid,end,temp;
 38     str = 1;end = n;
 39     while(str < end)
 40     {
 41         mid = (str+end)/2;
 42         temp = getsum(mid);
 43         if(temp < x)
 44         str = mid + 1;
 45         else
 46         end = mid;
 47     }
 48     return str;
 49 }
 50 int main()
 51 {
 52     int i,k,j,maxz,sum,sl,sr,key;
 53     while(scanf("%d%d",&n,&k)!=EOF)
 54     {
 55         for(i = n; i >= 1; i --)
 56         {
 57             scanf("%s%d",name[i],&s[i]);
 58         }
 59         for(i = 1;i <= n;i ++)
 60         {
 61             p[i] = 0;
 62             o[i] = 0;
 63         }
 64         for(i = 2;i <= n;i ++)
 65         {
 66             for(j = i;j <= n;j += i)
 67             {
 68                 o[j] ++;
 69             }
 70         }
 71         maxz = 0;
 72         key = 1;
 73         for(i = 2;i <= n;i ++)
 74         {
 75             if(maxz < o[i])
 76             {
 77                 maxz = o[i];
 78                 key = i;
 79             }
 80         }
 81         for(i = 1; i <= n; i ++)
 82         {
 83             insert(i,1);
 84         }
 85         k = n - k + 1;
 86         insert(k,-1);
 87         sum = n-1;
 88         for(i = 2;i <= key;i ++)
 89         {
 90             sl = getsum(k);
 91             sr = sum - sl;
 92             if(s[k] > 0)
 93             {
 94                 s[k] = s[k]%sum;
 95                 if(s[k] == 0) s[k] = sum;
 96                 if(sl >= s[k])
 97                 k = find(sl-s[k]+1);
 98                 else
 99                 k = find(sum-(s[k]-sl)+1);
100             }
101             else
102             {
103                 s[k] = -s[k];
104                 s[k] = (s[k])%sum;
105                 if(s[k] == 0) s[k] = sum;
106                 if(sr >= s[k])
107                 k = find(sl+s[k]);
108                 else
109                 k = find(s[k]-sr);
110             }
111             insert(k,-1);
112             sum --;
113         }
114         printf("%s %d\n",name[k],o[key]+1);
115     }
116     return 0;
117 }

 

posted @ 2013-06-18 09:27  Naix_x  阅读(244)  评论(0编辑  收藏  举报