注意题目中给的顺序是顺时针的,所以在数组中应该是倒着存的。左就是顺时针,右就是逆时针。各种调试之后,终于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 ",name[k],o[key]+1); 115 } 116 return 0; 117 }