트 리 배열 역순 맞 추기
5877 단어 알고리즘 총화데이터 구조트 리 배열 과 구간 트 리
우선: 제목 에서 a [i] 는 999, 999, 999 의 많 기 때문에 트 리 배열 을 사용 할 때 사용 하 는 트 리 배열 C [i] 는 비트 저장 소 와 비슷 한 배열 을 바탕 으로 하 는 것 이지 단순히 입력 배열 위 에 세 워 진 것 이 아니다.예 를 들 어 9, 1, 0, 5, 4 (최대 9) 를 입력 하면 C [i] 트 리 배열 의 구축 은 다음 과 같다. 아래 에 표 시 된 0, 1, 2, 3, 4, 5, 6, 7, 8 – 아래 표 시 는 9 배열 로 만들어 야 한다. 1, 0, 1, 0, 1 을 통 해 현재 99999999 라 는 숫자 가 500000 이라는 숫자 에 비해 매우 크기 때문에 배열 로 저장 하면...그러면 입력 한 데 이 터 를 저장 하기 위해 99999999 의 공간 이 필요 하 다.공간 을 낭비 하고 제목 도 허용 되 지 않 기 때문에 이산 화 작업 을 통 해
그럼 어떻게 이산 화 작업 을 합 니까?이산 화 는 흔히 사용 하 는 기법 이다. 때로는 데이터 범위 가 너무 커서 우리 가 처리 할 수 있 는 범 위 를 좁 힐 수 있다. 필요 한 것 은 구조 체 a [n] 를 구축 하 는 것 이다. v 는 입력 의 값 을 표시 하고 order 는 원 i 값 을 표시 하 며 하나의 배열 aa [n] 로 이산 화 된 값 을 저장 하 는 것 이다..order]=i; aa: 5 1, 2, 4, 3 즉 원래 의 9 는 순 서 를 거 쳐 5 위 에 있어 야 합 니 다. 현재 aa [1] = 5 는 원래 의 9 에 대응 하고 크기 순 서 는 변 하지 않 으 며 9 를 5 로 줄 였 습 니 다.
그러면 이산 화 된 후에 어떻게 역순 을 구 합 니까?솔직히 저 는 오래 생각 했 습 니 다. 먼저 update 함 수 를 통 해 하나의 수 를 삽입 하 는 것 입 니 다. 예 를 들 어 update (2, 1) 는 처음에 c [n] 이 0 이 고 삽입 후 + 1 입 니 다. 현재 나머지 는 0, c [2], c [4] = 1 입 니 다. 이것 은 앞 에 2 로 표시 되 어 있 는 숫자 2 가 있 습 니 다. 여기 가 관건 입 니 다. c [4] = 1 은 아래 에 4 로 표시 되 었 을 때 하나의 숫자 4 가 있 는 것 이 아니 라 4 이전 구간 에 있 는 모든 요소 의 합 이 1 이라는 뜻 입 니 다.즉, 하나의 수 2 가 있 습 니 다. 구체 적 으로 트 리 그림 을 볼 수 있 습 니 다. 그 다음 에 getsum 으로 하나의 수 를 삽입 하 는 앞 에 몇 개의 수 를 구하 면 현재 이 수 보다 작은 수의 개 수 를 계산 할 수 있 습 니 다. 그리고 아래 표 시 된 i - getsum (aa [i]) 을 통 해 그 보다 큰 수 를 얻 을 수 있 습 니 다. 즉, 역순 수 입 니 다.예: 1, 5 를 입력 하고 upDate (5, 1) 를 호출 하여 5 위 를 1, 2, 3, 4, 50, 0 1 로 설정 하여 1 - 5 에서 5 보다 작은 숫자 가 존재 합 니까?트 리 배열 의 getSum (5) = 1 작업 을 사 용 했 습 니 다. 현재 입력 한 아래 표 시 된 1 - getSum (5) = 0 으로 5 에 대한 역순 수 를 0 으로 얻 을 수 있 습 니 다.2. 2 를 입력 하고 upDate (2, 1) 를 호출 하여 2 위 를 1, 2, 3, 4, 0, 1, 0 1 / / 로 설정 합 니 다. 여기 서 실제 출력 하 는 것 은 0, 1, 1 입 니 다. 그러나 위 에서 말 한 것 처럼 여기 서 진정한 의 미 는 2 만 삽입 하 는 것 입 니 다. c [4] 는 앞의 c [2] 변화 로 인해 변화 하 는 것 입 니 다. 그리고 변화 가 있어 도 괜 찮 습 니 다. 뒤의 getsum 을 통 해 구 하 는 항상 구간 의 합, 뒤에 계산 할 때 c [4] 의 값 만 계산 합 니 다.앞 에는 더 하지 않 고 c [4] 의 값 은 바로 앞 에서 4 까지 이기 때문에 나타 난 숫자 와 계산 1 - 2 에 2 보다 작은 숫자 가 존재 합 니까?트 리 배열 의 getSum (2) = 1 동작 을 사 용 했 습 니 다. 현재 입력 한 아래 표 시 된 2 - getSum (2) = 1 을 사용 하면 2 에 대한 역순 수 를 1 로 얻 을 수 있 습 니 다.
POJ 2299 코드 는 다음 과 같 습 니 다.
#include
#include
#include
#include
#include
using namespace std;
const int maxn= 500005;
int aa[maxn];//
int c[maxn]; //
int n;
struct Node
{
int v;
int order;
}a[maxn];
bool cmp(Node a, Node b)
{
return a.v < b.v;
}
int lowbit(int k)
{
return k&(-k); // lowbit
}
void update(int t, int value)
{ // 0, (+1),
int i;
for (i = t; i <= n; i += lowbit(i))
c[i] += value;
}
int getsum(int t)
{ // ,
int i, sum = 0;
for (i = t; i >= 1; i -= lowbit(i))
sum += c[i];
return sum;
}
int main()
{
int i;
while (scanf("%d", &n), n)
{
for (i = 1; i <= n; i++) //
{
scanf("%d", &a[i].v);
a[i].order = i;
}
sort(a + 1, a + n + 1,cmp);// 1 n ,cmp
memset(c, 0, sizeof(c));
for (i = 1; i <= n; i++)
aa[a[i].order] = i;
__int64 ans = 0;
for (i = 1; i <= n; i++)
{
update(aa[i], 1);
ans += i - getsum(aa[i]); //
}
printf("%I64d
", ans);
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
2 - sat 의 건설 방법 및 해결 방안3. 만약 에 어떤 점 에서 떼 어 낸 두 점 이 모두 표시 되 지 않 았 다 면 우 리 는 먼저 첫 번 째 점 을 표시 하려 고 합 니 다. 만약 에 첫 번 째 점 을 표시 하면 일부 점 이 반드시 표시 되 어야 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.