[python] 백준 16978번: 수열과 쿼리 22

2025. 8. 5. 17:03·Algorithms/백준
반응형

링크: https://www.acmicpc.net/problem/16978

난이도: P4


문제


길이가 N인 수열 A1, A2, ..., AN이 주어진다. 이때, 다음 쿼리를 수행하는 프로그램을 작성하시오.

1 i v: Ai = v로 변경한다.
2 k i j: k번째 1번 쿼리까지 적용되었을 때, Ai, Ai+1, ..., Aj의 합을 출력한다.

 

입력


첫째 줄에 수열의 크기 N (1 ≤ N ≤ 100,000)이 주어진다.

둘째 줄에는 A1, A2, ..., AN이 주어진다. (1 ≤ Ai ≤ 1,000,000)

셋째 줄에는 쿼리의 개수 M (1 ≤ M ≤ 100,000)이 주어진다.

넷째 줄부터 M개의 줄에는 쿼리가 한 줄에 하나씩 주어진다. 1번 쿼리의 경우 1 ≤ i ≤ N, 1 ≤ v ≤ 1,000,000 이고, 2번 쿼리의 경우 1 ≤ i ≤ j ≤ N이고, 0 ≤ k ≤ (쿼리가 주어진 시점까지 있었던 1번 쿼리의 수)이다.

입력으로 주어지는 모든 수는 정수이다.

 

출력


모든 2번 쿼리마다 합을 출력한다.

 

예제 입력

5
1 2 3 4 5
7
1 2 5
2 0 1 3
2 1 1 3
1 4 2
2 0 2 5
2 1 2 5
2 2 2 5

예제 출력

6
9
14
17
15

풀이


기본적인 구간합 세그먼트 트리에서 쿼리에 변형이 추가된 문제다.

주어진 쿼리 순서대로 하면 시간초과가 발생할 수 밖에 없다.

우선, 1번쿼리를 add_q, 2번쿼리를 k_q로 따로 저장하고(이때, 기존의 k_q 순서를 idx로 추가해준다)

k_q를 k 오름차순으로 정렬해준다.

그렇게 되면 1번쿼리를 중복으로 진행할 필요 없이 최대 add_q 길이만큼만 진행해 주면 된다.

이후, 현재 1번쿼리의 어디까지 update진행되었는지 v로 따로 기억해주고 add_q를 돌아주면서 query 및 update를 적용해주고 

다시 k_q의 idx기준으로 정렬해준 뒤, 결과값들만 출력해준다.

 

제출코드

import sys
input=sys.stdin.readline

def build(le,ri,node):
    if le==ri:
        tree[node]=li[le]
        return
    mid=(le+ri)//2
    build(le,mid,node*2)
    build(mid+1,ri,node*2+1)
    tree[node]=tree[node*2]+tree[node*2+1]

def update(le,ri,node,idx,val):
    if idx<le or ri<idx:
        return 0
    if le==ri==idx:
        tree[node]=val
        return
    mid=(le+ri)//2
    update(le,mid,node*2,idx,val)
    update(mid+1,ri,node*2+1,idx,val)
    tree[node]=tree[node*2]+tree[node*2+1]

def query(st,end,node,le,ri):
    if end<le or ri<st:
        return 0
    if st<=le and ri<=end:
        return tree[node]
    mid=(le+ri)//2
    return query(st,end,node*2,le,mid)+query(st,end,node*2+1,mid+1,ri)


N=int(input())
li=[0]+list(map(int,input().split()))
tree=[0]*(N*4)
M=int(input())
add_q,k_q=[],[]
for idx in range(M):
    tmp=list(map(int,input().split()))
    if len(tmp)==3:
        _,i,v=tmp
        add_q.append([i,v])
    else:
        _,k,i,j=tmp
        k_q.append([k,i,j,idx])
k_q.sort(key=lambda x:x[0])
build(0,N,1)

v=0
for now in range(len(k_q)):
    k,i,j,idx=k_q[now]
    if v<k:
        for tar in range(v,k):
            tar_idx,tar_val=add_q[tar]
            update(0,N,1,tar_idx,tar_val)
    tmp_val=query(i,j,1,0,N)
    k_q[now].append(tmp_val)
    v=k
k_q.sort(key=lambda x:x[3])
for i in k_q:
    print(i[4])

 


틀린 부분이 있거나 인용한 부분에 대해 문제가 있을 시
댓글로 알려주시면 감사하겠습니다.
반응형

'Algorithms > 백준' 카테고리의 다른 글

[python] 백준 14463번 : 소가 길을 건너간 이유9  (2) 2025.07.31
[python] 백준 1219번 : 오민식의 고민  (1) 2025.06.13
[python] 백준 3020번: 개똥벌레  (0) 2025.06.10
[python] 백준 11062번 : 카드게임  (0) 2025.05.26
[python] 백준 14621번 : 나만 안되는 연애  (0) 2025.05.20
'Algorithms/백준' 카테고리의 다른 글
  • [python] 백준 14463번 : 소가 길을 건너간 이유9
  • [python] 백준 1219번 : 오민식의 고민
  • [python] 백준 3020번: 개똥벌레
  • [python] 백준 11062번 : 카드게임
wwwjong
wwwjong
wwwjong 님의 블로그 입니다.
  • wwwjong
    wwwjong 님의 블로그
    wwwjong
  • 전체
    오늘
    어제
    • 분류 전체보기 (42) N
      • Programming (12) N
        • 트러블슈팅 (3)
        • Dev notes (9) N
      • CS (2)
        • Infra (2)
      • 개발환경 (6)
        • Ubuntu (6)
      • Algorithms (15)
        • 백준 (8)
        • Algorithm (3)
        • 코드트리 (3)
        • Programmers (1)
      • Study (6)
        • 면접을 위한 CS 전공지식 노트 (6)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    딥러닝
    skala
    CS
    ubuntu
    코딩테스트
    Server
    Nginx
    AI
    코테공부
    코드트리
    docker compose
    면접을 위한 CS 전공지식 노트
    Jenkins
    ubuntu server
    LLM
    computer science
    백준
    트랜스포머
    docker
    transformer
  • 최근 댓글

  • 최근 글

  • 반응형
  • hELLO· Designed By정상우.v4.10.1
wwwjong
[python] 백준 16978번: 수열과 쿼리 22
상단으로

티스토리툴바