티스토리 뷰
DS\Algo/Segment Tree
BOJ 13537 수열과 쿼리 1 (Persistent Segment Tree version)
MathTrauma 2022. 8. 13. 01:21
문제 링크 : https://www.acmicpc.net/problem/13537
13537번: 수열과 쿼리 1
길이가 N인 수열 A1, A2, ..., AN이 주어진다. 이때, 다음 쿼리를 수행하는 프로그램을 작성하시오. i j k: Ai, Ai+1, ..., Aj로 이루어진 부분 수열 중에서 k보다 큰 원소의 개수를 출력한다.
www.acmicpc.net
수열이 모두 입력되고 나서 쿼리가 따로 주어지므로 소위 off-line query로 해결하라는 거 같은데...
익숙해지면 persistent segment tree 가 구현하기 오히려 편하게 느껴진다.
persistent segment tree는 배열의 원소가 하나 추가될 때 마다 세그먼트 트리를 하나씩 만든다.
이 과정에서 메모리, 시간이 문제가 되니까, 갱신되는 경로 상의 node 는 새로 만들고 나머지는 이전 트리의 node를 가져다 쓴다.
#include<bits/stdc++.h>
using namespace std;
struct Node{
int v;
Node *nl, *nr;
Node() : v{0}, nl{nullptr}, nr{nullptr} {}
Node(int v, Node *l, Node *r) : v{v}, nl{l}, nr{r} {}
Node* make(int il, int ir, int p){
if(p<il || ir<p) return this;
if(il==ir) return new Node(v+1, nullptr, nullptr);
int mid=il+ir>>1;
return new Node(v+1, nl->make(il,mid,p), nr->make(mid+1, ir, p));
}
} *root[100001], *null;
int qry(int il, int ir, Node *S, Node *E, int p){
if(p<il) return 0;
if(ir<=p) return E->v - S->v;
int mid=il+ir>>1;
return qry(il,mid,S->nl, E->nl,p)+qry(mid+1, ir, S->nr, E->nr,p);
}
int arr[100001], cpy[100001];
int main(){
int N; scanf("%d",&N);
for(int i=1;i<=N;i++){
scanf("%d",&arr[i]);
cpy[i]=arr[i];
}
sort(cpy+1,cpy+N+1);
int sz=unique(cpy+1, cpy+N+1)-cpy;
null=new Node();
null->nl=null->nr=null;
for(int i=1;i<=N;i++){
int p=lower_bound(cpy+1,cpy+sz,arr[i])-cpy;
if(i==1) root[i]=null->make(0, sz, p);
else root[i]=root[i-1]->make(0, sz, p);
}
int m; scanf("%d",&m);
for(int i=0;i<m;i++){
int a,b,k; scanf("%d%d%d",&a,&b,&k);
int p=upper_bound(cpy+1, cpy+sz, k)-cpy;
printf("%d\n", (b-a+1) - qry(0,sz, a==1?null:root[a-1], root[b], p-1));
}
}
값의 크기에 따른 순서를 index를 이용해서 저장한다.
il, ir 은 index 의 좌우를 뜻한다.(index 범위를 나타낸다.)
sort, unique 로 소위 좌표 압축을 해서 크기 순서를 정한다.
반응형
'DS\Algo > Segment Tree' 카테고리의 다른 글
BOJ 1168 요세푸스 문제 2 (0) | 2022.08.23 |
---|---|
BOJ 18436 수열과 쿼리 37 (0) | 2022.08.23 |
BOJ 9345 DVDs (0) | 2022.08.15 |
BOJ 7578 공장 (0) | 2022.08.13 |
BOJ 11658 구간 합 구하기 3 (0) | 2022.08.02 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- Reference
- nearest common ancestor
- BOJ
- fenwick tree
- Vim
- dynamic programming
- 정수론
- C++ big number
- Shell Programming
- segment tree
- shell
- 백준
- max flow
- lazy propagation
- RUBY
- 세그먼트 트리
- Aho-Corasick
- bash
- map
- script
- math font
- persistent segment tree
- bash script
- JavaScript
- Dijkstra
- number theory
- stack
- javascript array
- python3
- 다익스트라
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함