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 }

 

你可能感兴趣的:(树状数组)