-
Notifications
You must be signed in to change notification settings - Fork 94
/
Copy pathAlmost sorted interval.py
110 lines (90 loc) · 2.72 KB
/
Almost sorted interval.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
"""
Shik loves sorted intervals. But currently he does not have enough time to sort all the numbers. So he decided to use
Almost sorted intervals. An Almost sorted interval is a consecutive subsequence in a sequence which satisfies the
following property:
The first number is the smallest.
The last number is the largest.
Please help him count the number of almost sorted intervals in this permutation.
Input Format
The first line contains an integer N.
The second line contains a permutation from 1 to N.
"""
__author__ = 'Danyang'
class Solution(object):
def solve(self, cipher):
"""
left[i] : the nearest (first) position left to i and with value larger than a[i] .
right[i] : the nearest (first) position right to i and with value smaller than a[i] .
use stack to find it.
interval tree
:param cipher:
:return:
"""
# TODO
def solve_time_out(self, cipher):
"""
chaining >, dp
similar to find Find Maximum Index Product
L[i] is the nearest item on the right larger than A[i]
S[i] is the nearest item on the right smaller than A[i]
:type cipher: list
:param cipher
"""
A = cipher
L = [-1 for _ in A]
S = [-1 for _ in A]
for i in xrange(len(A) - 2, -1, -1):
idx = i + 1
while idx != -1:
if A[idx] < A[i]:
idx = L[idx]
else:
break
L[i] = idx
idx = i + 1
while idx != -1:
if A[idx] > A[i]:
idx = S[idx]
else:
break
S[i] = idx
cnt = 0
for i in xrange(len(A)):
cnt += 1
l = L[i]
s = S[i]
while l != -1 and (s == -1 or s > l):
cnt += 1
l = L[l]
return cnt
def solve_error(self, cipher):
"""
sliding window, error.
:param cipher: the cipher
"""
A = cipher
N = len(A)
start = 0
end = 1 # [0, 1)
cnt = 0
while end < N:
if A[end] > A[end - 1]:
end += 1
else:
cnt += self.count(start, end)
start = end
end += 1
cnt += self.count(start, end)
return cnt
def count(self, start, end):
l = end - start
return (l + 1) * l / 2
if __name__ == "__main__":
import sys
f = open("0.in", "r")
# f = sys.stdin
N = int(f.readline().strip())
cipher = map(int, f.readline().strip().split(' '))
# solve
s = "%s\n" % (Solution().solve(cipher))
print s,