세그먼트 트리
update 시간 복잡도 : Log(N)
query 시간 복잡도 : Log(N)
c : 현재 노드
l, r : 현재 노드의 값의 범위
s, f : 찾으려는 값의 범위
val : update 되는 값
기본 코드
ll update(ll c, ll l, ll r ,ll f,ll val)
{
if(!(l<=f&&f<=r))
return arr[c];
else if(l==r)
return arr[c] = val;
ll mid = (l+r)/2;
return arr[c] = update(c*2,l,mid,f,val)+update(c*2+1,mid+1,r,f,val);
}
ll query(ll c, ll l, ll r, ll s, ll f)
{
if(r<s||f<l)
return 0;
else if(s<=l&&r<=f)
return arr[c];
ll mid = (l+r)/2;
return query(c*2,l,mid,s,f)+query(c*2+1,mid+1,r,s,f);
}
기본 예제
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#define MAX 1000005
#define INF 987654321
#define MOD 31991
#pragma warning(disable:4996)
using namespace std;
typedef long long ll;
typedef pair<int, int> pi;
ll n,m,k,a,b,c,arr[MAX*4];
ll update(ll c, ll l, ll r ,ll f,ll val)
{
if(!(l<=f&&f<=r))
return arr[c];
else if(l==r)
return arr[c] = val;
ll mid = (l+r)/2;
return arr[c] = update(c*2,l,mid,f,val)+update(c*2+1,mid+1,r,f,val);
}
ll query(ll c, ll l, ll r, ll s, ll f)
{
if(r<s||f<l)
return 0;
else if(s<=l&&r<=f)
return arr[c];
ll mid = (l+r)/2;
return query(c*2,l,mid,s,f)+query(c*2+1,mid+1,r,s,f);
}
int main()
{
scanf("%lld %lld %lld",&n,&m,&k);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a);
update(1,1,n,i,a);
}
for(int i=0;i<m+k;i++)
{
scanf("%lld %lld %lld",&a,&b,&c);
if(a==1)
update(1,1,n,b,c);
else
printf("%lld\n",query(1,1,n,b,c));
}
return 0;
}'IT > 알고리즘 및 자료구조' 카테고리의 다른 글
| [알고리즘 정리] 위상 정렬 (0) | 2018.09.30 |
|---|---|
| [알고리즘 정리] 이분 매칭 (0) | 2018.09.30 |
| [알고리즘 정리] 이분 탐색 (0) | 2018.09.14 |
| [알고리즘 정리] 그라함 알고리즘(Graham’s scan) 알고리즘 (0) | 2018.08.26 |
| [알고리즘] 구조체를 이용한 행렬의 곱 구현 (0) | 2018.08.11 |