백준 1280번 나무심기
문제링크: https://www.acmicpc.net/problem/1280
사용한 알고리즘: 펜윅트리
나무를 심을 때 마다 발생하는 비용을 곱한 합을 출력하는 문제였습니다.
문제풀이는 다음과 같습니다.
(1) 나무들의 심는 위치들을 펜윅트리로 구현합니다.
(2) i번째에 나무를 심을 때, (왼쪽나무개수Xi) - (왼쪽 나무(i보다 작은)들의 비용합) 과 (오른쪽 나무(i보다 큰)들의 비용합) - (오른쪽나무개수Xi) 를 더해 이를 구하고자 하는 값에 곱해줍니다.
(3) Moudlo 1000000007 을 주었으므로 이를 신경써주며 위 과정을 통해 답을 얻습니다.
2<=N 이라는 조건을 주었으므로 N=1인 경우는 생각할 필요가 없었습니다.
혹시 펜윅트리에대한 자세한 내용이 궁금한 분들은 아래 링크에 잘 정리되어 잇으니 참고해주세요.
https://www.acmicpc.net/blog/view/21
사용한 알고리즘: 펜윅트리
나무를 심을 때 마다 발생하는 비용을 곱한 합을 출력하는 문제였습니다.
문제풀이는 다음과 같습니다.
(1) 나무들의 심는 위치들을 펜윅트리로 구현합니다.
(2) i번째에 나무를 심을 때, (왼쪽나무개수Xi) - (왼쪽 나무(i보다 작은)들의 비용합) 과 (오른쪽 나무(i보다 큰)들의 비용합) - (오른쪽나무개수Xi) 를 더해 이를 구하고자 하는 값에 곱해줍니다.
(3) Moudlo 1000000007 을 주었으므로 이를 신경써주며 위 과정을 통해 답을 얻습니다.
2<=N 이라는 조건을 주었으므로 N=1인 경우는 생각할 필요가 없었습니다.
혹시 펜윅트리에대한 자세한 내용이 궁금한 분들은 아래 링크에 잘 정리되어 잇으니 참고해주세요.
https://www.acmicpc.net/blog/view/21
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
#include <bits/stdc++.h> | |
using namespace std; | |
#define ll long long | |
const int MOD = 1000000007; | |
const int MAX = 222222; | |
int N; | |
ll ans, number[MAX+1], value[MAX+1]; | |
int Li(int x){ | |
return x&(-x); | |
} | |
ll sum(int i){ | |
ll temp = 0; | |
while(i>0){ | |
temp += value[i]; | |
i -= Li(i); | |
} | |
return temp; | |
} | |
int Nsum(int i){ | |
int nnn = 0; | |
while(i>0){ | |
nnn += number[i]; | |
i -= Li(i); | |
} | |
return nnn; | |
} | |
void update(int i, int V){ | |
while(i<=MAX){ | |
value[i] += V; | |
number[i] += 1; | |
i += Li(i); | |
} | |
} | |
int main(){ios_base::sync_with_stdio(false); cout.tie(NULL); cin.tie(NULL); | |
cin >> N; | |
for (int i = 0; i < N; ++i){ | |
int where; | |
cin >> where; | |
// 펙윅은 0 처리를 못하니 좌표를 그냥 +1 해주었습니다. | |
where++; | |
ll leftcnt = Nsum(where-1); | |
ll rightcnt = Nsum(MAX)-Nsum(where); | |
ll leftVal = sum(where-1); | |
ll rightVal = sum(MAX)-sum(where); | |
// 왼쪽 + 오른쪽 | |
ll temp = where*leftcnt - leftVal; | |
temp%=MOD; | |
temp += rightVal - where*rightcnt; | |
temp%=MOD; | |
ans *= temp; | |
ans %= MOD; | |
update(where,where); | |
if(i==0) ans=1LL; | |
} | |
cout << ans%MOD << '\n'; | |
return 0; | |
} |
댓글
댓글 쓰기
긴 글 읽어주셔서 감사합니다.
궁금한게 있으시다면 댓글 달아주세요!