Topic links: http://codeforces.com/problemset/problem/1168/A
Question is intended: to an array, the array elements in the range of 0 ~ n, each time you can select several elements (ai + 1)% m of the operation, the array was asked to make the minimum number of non-increasing operations.
Thinking: because each can be selected from several elements, greedy thought, if the first element than m, m modulo of the minimum value is 0, so that it is equal to zero like, is assumed to operate x times, each after adding elements x, after modulo m smaller than the front long enough, it is determined in turn for each element of the array can meet, using a binary search to find the operands x, x is the answer.
AC Code:
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 const int maxn = 3e5 + 5; 5 int a[maxn]; 6 int n,m; 7 8 bool check(int x) 9 { 10 int last = a[0]; 11 if(a[0] + x >= m) last = 0;//如果 a[0] 经过x次变换后大于 m 那么 a[0] 可以看做 0 。 12 for(int i = 1;i < n;i++) 13 { 14 int temp = -1;//存放a[i]与last更大的那个。 15 if(a[i] >= last) 16 { 17 temp = a[i]; 18 //如果经过x次变换后 a[i] 可以比前面大,那么temp存放前面的值就行。 19 if(a[i] + x >= m && (a[i] + x) % m >= last) 20 { 21 temp = last; 22 } 23 } 24 else if(a[i] + x >= last) temp = last; 25 if(temp == -1) return false;//找不到比前面更大的a[i]。 26 last = temp; 27 } 28 return true; 29 } 30 int main() 31 { 32 scanf("%d%d",&n,&m); 33 for(int i = 0 ;i < n;i++) 34 { 35 scanf("%d",&a[i]); 36 } 37 int l = 0,r = m + 1,ans = 0; 38 while(l <= r) 39 { 40 int mid = (l + r) >> 1; 41 if(check(mid)) r = mid - 1,ans = mid; 42 else l = mid + 1; 43 } 44 printf("%d\n",ans); 45 return 0; 46 }