-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
114 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import sys | ||
from bisect import bisect_left, bisect_right | ||
|
||
n = int(input()) | ||
sqrt_n = int(n ** 0.5) | ||
arr = list(map(int, input().split())) | ||
m = int(input()) | ||
queries = [list(map(int, sys.stdin.readline().split())) for _ in range(m)] | ||
|
||
buckets = [] | ||
idx = 0 | ||
while idx < n: | ||
j = min(idx + sqrt_n, n) | ||
buckets.append(sorted(arr[idx:j])) | ||
idx += sqrt_n | ||
# print(buckets) | ||
# arr[1:4] => 1번부터 3번까지란 뜻 | ||
|
||
for q in queries: | ||
if q[0] == 1: | ||
i, j, k = q[1] - 1, q[2] - 1, q[3] | ||
ans = 0 | ||
for idx, bucket in enumerate(buckets): | ||
if idx * sqrt_n <= i < (idx + 1) * sqrt_n: | ||
# i랑 j 둘다 bucket 범위 안에 있을 경우 | ||
if idx * sqrt_n <= j < (idx + 1) * sqrt_n: | ||
# naive하게 계산 | ||
sub_arr = arr[i:j+1] | ||
sub_arr.sort() | ||
ans += len(sub_arr) - bisect_right(sub_arr, k) | ||
break # j 범위까지가 마지막이므로 반복문 중단 | ||
# i만 bucket 범위 안에 있을 경우 | ||
else: | ||
sub_arr = arr[i:(idx + 1) * sqrt_n] | ||
sub_arr.sort() | ||
ans += len(sub_arr) - bisect_right(sub_arr, k) | ||
# i는 아니지만 j는 bucket 범위 안에 있을 경우 | ||
elif idx * sqrt_n <= j < (idx + 1) * sqrt_n: | ||
# naive하게 계산 | ||
sub_arr = arr[idx*sqrt_n:j+1] | ||
sub_arr.sort() | ||
ans += len(sub_arr) - bisect_right(sub_arr, k) | ||
break # j 범위까지가 마지막이므로 반복문 중단 | ||
# i와 j 사이에 bucket의 모든 인덱스가 포함될 경우 | ||
elif i <= idx * sqrt_n and (idx + 1) * sqrt_n <= j: | ||
sub_arr = bucket | ||
ans += len(sub_arr) - bisect_right(sub_arr, k) | ||
print(ans) | ||
else: | ||
i, k = q[1] - 1, q[2] | ||
for idx, bucket in enumerate(buckets): | ||
# 찾으려는 i가 bucket 범위 안에 있다면 | ||
if idx * sqrt_n <= i < (idx + 1) * sqrt_n: | ||
prev_v = arr[i] # 원래 값 | ||
arr[i] = k # 기본 배열을 새로운 값으로 업데이트 | ||
prev_idx = bisect_left(bucket, prev_v) # 원래 값이 정렬된 리스트에 있는 위치 | ||
bucket[prev_idx] = k # bucket을 새로운 값으로 업데이트 | ||
bucket.sort() # 재정렬 | ||
break |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import math | ||
import sys | ||
|
||
|
||
class SegTree: | ||
def __init__(self, arr): | ||
self.arr = arr | ||
self.n = len(arr) | ||
self.tree = [0] * pow(2, math.ceil(math.log(self.n, 2) + 1)) | ||
self.loc = [0] * self.n | ||
self.init_seg(0, self.n - 1) | ||
|
||
def init_seg(self, s, e, i=1): | ||
if s == e: | ||
self.loc[s] = i | ||
self.tree[i] = 1 if self.arr[s] > 0 else (-1 if self.arr[s] < 0 else 0) | ||
# self.tree[i] = self.arr[s] | ||
return self.tree[i] | ||
m = (s + e) >> 1 | ||
self.tree[i] = self.init_seg(s, m, i << 1) * self.init_seg(m + 1, e, i << 1 | 1) | ||
return self.tree[i] | ||
|
||
def search(self, s, e, l, r, i=1): | ||
if e < l or s > r: | ||
return 1 | ||
if l <= s and e <= r: | ||
return self.tree[i] | ||
m = (s + e) >> 1 | ||
return self.search(s, m, l, r, i << 1) * self.search(m + 1, e, l, r, i << 1 | 1) | ||
|
||
def update(self, i, x): | ||
idx = self.loc[i] | ||
x = 1 if x > 0 else (-1 if x < 0 else 0) | ||
self.tree[idx] = x | ||
while idx > 1: | ||
idx //= 2 | ||
self.tree[idx] = self.tree[idx << 1] * self.tree[idx << 1 | 1] | ||
|
||
|
||
while True: | ||
try: | ||
n, k = map(int, sys.stdin.readline().split()) | ||
a = list(map(int, sys.stdin.readline().split())) | ||
seg = SegTree(a) | ||
for i in range(k): | ||
inst, *args = sys.stdin.readline().split() | ||
args = tuple(map(int, args)) | ||
if inst == 'C': | ||
seg.update(args[0] - 1, args[1]) | ||
elif inst == 'P': | ||
res = seg.search(0, n - 1, args[0] - 1, args[1] - 1) | ||
print('+' if res > 0 else ('-' if res < 0 else '0'), end='') | ||
print() | ||
except: | ||
break |