fork download
  1. def getMinErrors(errorString, x, y):
  2. MOD = 10**9 + 7
  3. n = len(errorString)
  4. pre0 = [0] * (n + 1) # prefix count of 0s
  5. pre1 = [0] * (n + 1) # prefix count of 1s
  6. preq = [0] * (n + 1) # prefix count of wildcards
  7.  
  8. # Build prefix sums
  9. for i in range(n):
  10. pre0[i+1] = pre0[i] + (1 if errorString[i] == '0' else 0)
  11. pre1[i+1] = pre1[i] + (1 if errorString[i] == '1' else 0)
  12. preq[i+1] = preq[i] + (1 if errorString[i] == '!' else 0)
  13.  
  14. suf0 = [0] * (n + 1)
  15. suf1 = [0] * (n + 1)
  16. sufq = [0] * (n + 1)
  17. for i in reversed(range(n)):
  18. suf0[i] = suf0[i+1] + (1 if errorString[i] == '0' else 0)
  19. suf1[i] = suf1[i+1] + (1 if errorString[i] == '1' else 0)
  20. sufq[i] = sufq[i+1] + (1 if errorString[i] == '!' else 0)
  21.  
  22. # Count total number of wildcards
  23. total_q = preq[n]
  24.  
  25. # Try all possible cuts: wildcards before i are '0', after i are '1'
  26. # And also wildcards before i are '1', after i are '0'
  27. min_err = float('inf')
  28.  
  29. # Prepare for cut: all wildcards as '0' or as '1'
  30. def count_errors(a, b):
  31. # Count number of 01 and 10 subsequences
  32. cnt0 = cnt1 = cntq = 0
  33. cnt_01 = cnt_10 = 0
  34. for c in errorString:
  35. if c == '0':
  36. cnt0 += 1
  37. cnt_10 += cnt1
  38. elif c == '1':
  39. cnt1 += 1
  40. cnt_01 += cnt0
  41. else:
  42. cnt0 += a
  43. cnt1 += b
  44. cnt_10 += cnt1 * a
  45. cnt_01 += cnt0 * b
  46. return cnt_01 * x + cnt_10 * y
  47.  
  48. # Try all wildcards as '0'
  49. err0 = count_errors(1, 0)
  50. # Try all wildcards as '1'
  51. err1 = count_errors(0, 1)
  52. min_err = min(err0, err1)
  53.  
  54. # Now try for all possible cuts
  55. # Precompute: for each i, how many wildcards up to i are assigned '0', after are '1'
  56. pre_q0 = 0
  57. for cut in range(n + 1):
  58. zeros = pre0[cut] + preq[cut] # 0s and ! assigned 0 to the left
  59. ones = suf1[cut] + sufq[cut] # 1s and ! assigned 1 to the right
  60. # Number of 01 subsequences: number of 0s left * number of 1s right
  61. num_01 = zeros * ones
  62. # Number of 10 subsequences: number of 1s left * number of 0s right
  63. num_10 = pre1[cut] * suf0[cut]
  64. err = num_01 * x + num_10 * y
  65. min_err = min(min_err, err)
  66. return min_err % MOD
  67.  
  68. print(getMinErrors('0!!1!1', 2, 3)) # Output: 10
  69. print(getMinErrors('!!!!!!', 23, 47)) # Output: 0
Success #stdin #stdout 0.11s 14252KB
stdin
10
aba
geeksforgeeks
geeksforgeeks
geeksforgeeks
geeksforgeeks
geeksforgeeks
geeksforgeeks
geeksforgeeks
geeksforgeeks
geeksforgeeks
stdout
0
0