結果
問題 | No.3059 Range Tournament |
ユーザー |
|
提出日時 | 2025-03-14 22:29:48 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 3,018 ms / 4,000 ms |
コード長 | 4,689 bytes |
コンパイル時間 | 306 ms |
コンパイル使用メモリ | 82,372 KB |
実行使用メモリ | 260,256 KB |
最終ジャッジ日時 | 2025-03-14 22:31:02 |
合計ジャッジ時間 | 67,209 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 27 |
ソースコード
import sys,time from itertools import permutations from heapq import heappop,heappush from collections import deque import random import bisect from math import ceil,floor input = lambda :sys.stdin.readline().rstrip() mi = lambda :map(int,input().split()) li = lambda :list(mi()) class SegmentTree: def __init__(self, init_val, segfunc, ide_ele): n = len(init_val) self.segfunc = segfunc self.ide_ele = ide_ele self.num = 1 << (n - 1).bit_length() self.tree = [ide_ele] * 2 * self.num self.size = n for i in range(n): self.tree[self.num + i] = init_val[i] for i in range(self.num - 1, 0, -1): self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1]) def update(self, k, x): k += self.num self.tree[k] = x while k > 1: k >>= 1 self.tree[k] = self.segfunc(self.tree[2*k], self.tree[2*k+1]) def query(self, l, r): if r==self.size: r = self.num res = self.ide_ele l += self.num r += self.num while l < r: if l & 1: res = self.segfunc(res, self.tree[l]) l += 1 if r & 1: res = self.segfunc(res, self.tree[r-1]) l >>= 1 r >>= 1 return res class SparseTable(): def __init__(self,A,merge_func,ide_ele): N = len(A) self.merge_func = merge_func self.lg = [0]*(N + 1) for i in range(2, N+1): self.lg[i] = self.lg[i >> 1] + 1 self.pow_2 = [pow(2,i) for i in range(20)] self.table = [None]*(self.lg[N] + 1) st0 = self.table[0] = [a for a in A] b = 1 for i in range(self.lg[N]): st0 = self.table[i+1] = [self.merge_func(u,v) for u, v in zip(st0, st0[b:])] b <<= 1 def query(self,s,t): b = t-s+1 m = self.lg[b] return self.merge_func(self.table[m][s],self.table[m][t-self.pow_2[m]+1]) def solve(N,P,Q,query): K = 20 imos = [[0]*(N+1) for k in range(K)] res = [0] * N seg = SegmentTree(P,max,-1) ST = SparseTable(P,max,-1) for l,r in query: l,r,k = l,r,0 amari = [] imos[0][l] -= 1 imos[0][r] += 1 while True: imos[k][l] += 1 imos[k][r] -= 1 #print(l,r,k,amari) if not amari: n = (r-l)>>k if n == 1: break if n & 1 == 0: k += 1 else: res[ST.query(l,l+(2<<k)-1)] += 1 amari = [ST.query(l,l+(2<<k)-1), ST.query(r-(1<<k),r-1)] l,r = l+(2<<k),r-(1<<k) k += 1 else: res[max(amari)] += 1 n = ((r-l)>>k) + 1 if n == 1: break if n & 1 == 0: amari.append(seg.query(r-(1<<k),r)) l,r = l,r-(1<<k) k += 1 else: res[ST.query(l,l+(2<<k)-1)] += 1 amari.append(ST.query(l,l+(2<<k)-1)) l,r = l+(2<<k),r k += 1 for k in range(K): for i in range(N): if i+(1<<k) <= N: imos[k][i+(1<<k)] += imos[k][i] for i in range(N-(1<<k)+1): idx = ST.query(i,i+(1<<k)-1) res[idx] += imos[k][i] return res def solve_brute(N,P,Q,query): res = [0] * N for l,r in query: A = deque(P[l:r]) while len(A) > 1: a = A.popleft() b = A.popleft() res[max(a,b)] += 1 A.append(max(a,b)) return res while False: #N = random.randint(2,20) N = 2 * 10**5 P = [i for i in range(N)] random.shuffle(P) #Q = random.randint(2,20) Q = 2 * 10**5 query = [] for i in range(Q): l = random.randint(0,N-1) r = random.randint(l+1,N) query.append((l,r)) #exp = solve_brute(N,P,Q,query) res = solve(N,P,Q,query) print(sum(res)) continue if exp!=res: print("WA") print(N,Q) print(P) print(query) print(exp) print(res) break else: print("AC",N,Q,sum(exp)) N = int(input()) P = [int(p)-1 for p in input().split()] Q = int(input()) query = [] for _ in range(Q): l,r = mi() query.append((l-1,r)) print(*solve(N,P,Q,query),sep="\n")