목차
문법
알고리즘
따라야 할 방법
방법-2
예 1
출력
示例 2
输出
结论
백엔드 개발 C++ 주어진 숫자보다 크거나 같은 배열의 요소 수를 쿼리하고 업데이트합니다.

주어진 숫자보다 크거나 같은 배열의 요소 수를 쿼리하고 업데이트합니다.

Sep 05, 2023 am 08:25 AM
요소 수 쿼리 요소 수 업데이트 배열 쿼리 업데이트

주어진 숫자보다 크거나 같은 배열의 요소 수를 쿼리하고 업데이트합니다.

세그먼트 트리의 도움으로 배열을 성공적으로 업데이트하고 범위 쿼리를 수행할 수 있습니다. 업데이트하면 알려진 데이터 구조 세그먼트 트리를 사용하여 계산할 수 있습니다. 배열의 요소 수는 no보다 크거나 같습니다.

  • Query - [l, r] 범위에 x보다 크거나 유사한 항목이 몇 개 있는지 알아보세요.

    • 범위 [l, r]이 세그먼트 트리의 현재 노드가 나타내는 세그먼트를 넘어 완전히 확장되면 0이 제공됩니다.

    • 카운트. 간격 [l, r]이 세그먼트 트리의 현재 노드가 나타내는 세그먼트 내에 완전히 있는 경우 x보다 크거나 유사한 범위 [l, r]에 있는 요소 수입니다.

    • 그렇지 않은 경우 현재 노드의 왼쪽 및 오른쪽 하위 노드를 재귀적으로 ping하여 수집된 총 개수를 반환합니다.

  • Update - 인덱스 i의 요소에 v 값을 추가합니다. 이번 업데이트에는 다음 알고리즘을 적용합니다 -

    • 세그먼트 트리의 현재 노드 표시 범위에 인덱스 i가 없으면 아무런 작업도 수행되지 않습니다.

    • 인덱스 i의 값이 x보다 크거나 같으면 선분 트리의 현재 노드가 나타내는 간격에서 x보다 크거나 같은 요소의 개수를 업데이트합니다. 또는 x와 같고 이를 증가시킨 다음 현재 노드를 재귀적으로 업데이트합니다. 왼쪽 및 오른쪽 하위 요소 노드입니다.

    • 세그먼트 트리의 루트 노드에서 [0, n-1] 범위의 쿼리를 실행할 수 있습니다. 여기서 n은 총 개수입니다. x보다 크거나 같은 배열의 항목 수입니다.

문법

1. 처음부터 세그먼트 트리 및 배열 생성 -

으아악

2. 업데이트(변경) 절차 수행 -

으아악

3. 다음 쿼리 작업을 수행합니다. -

으아악

4. 쿼리 작업을 사용하여 수량을 계산합니다. 지정된 값보다 크거나 같은 요소, 배열 및 세그먼트 트리를 업데이트하는 업데이트 작업 -

으아악

알고리즘

업데이트를 사용하여 숫자를 계산할 수 있는 방법은 다음과 같습니다. 지정된 값보다 크거나 같은 배열 멤버 -

  • 1단계 - 시작 값을 저장할 n 크기의 배열 A를 만듭니다.

  • 2단계 - 최소 범위 쿼리를 표시하려면 크기 4*n의 세그먼트 트리 T를 초기화합니다.

  • 3단계 - build(T, A, 1, 0, n-1) 함수를 사용하여 세그먼트 트리 T를 만듭니다. 여기서 build(T, A, v, tl, tr)는 A의 값을 사용합니다. 범위 [tl, tr]를 생성하고 결과를 T의 노드 v에 넣습니다.

  • 4단계 - 크기 n의 배열 C를 만들고 지정된 수보다 크거나 같은 항목 수로 초기화합니다.

  • 5단계 - 개수 쿼리의 범위 합계를 나타내기 위해 시작 크기가 4*n인 세그먼트 트리 S를 만듭니다.

  • 6단계 - build(S, C, 1, 0, n-1) 함수를 호출합니다. 여기서 build(S, C, v, tl, tr)는 [tl, tr], C의 값을 사용하고 결과를 S의 노드 v에 유지합니다.

  • 7단계 - 각 "x보다 크거나 같은 요소 개수 계산" 쿼리에 응답합니다. -

  • 배열 A의 [l, r] 범위에서 최소값을 찾으려면 쿼리(T, 1, 0, n-1, l, r) 함수를 호출하세요. 결과가 m이라고 가정합니다.

    m이 x보다 크거나 같으면 함수 쿼리(S, 1, 0, n-1, l, r)를 사용하여 총 개수를 구합니다. x보다 크거나 같은 배열 C의 간격 [l, r]에 있는 항목 수입니다. 결과는 다음과 같습니다. c.

    그렇지 않다면 c를 0으로 설정하세요.

  • 8단계 - 유형이 변경될 때마다 "A[i]의 값을 v로 설정" -

  • [tl,tr] 범위에서 선분 트리 T의 노드 v를 업데이트하고 update(T,v,tl,tr,i,val) 함수를 호출합니다. 여기서 update(T,v,tl,tr,i , val) 인덱스 i의 값을 val로 설정하여 세그먼트 트리 T의 노드 v를 변경합니다.

    update(S, 1, 0, n-1, i, (v >= x)) 함수를 사용하여 [tl, tr] 범위의 선분 트리 노드 v를 업데이트합니다. 여기서 update(S, v, tl , tr, i, val)은 x보다 크거나 같은 항목 수에 val을 추가하여 노드 v를 업데이트합니다.

  • 9단계 - 7단계와 8단계를 다시 반복합니다.

따라야 할 방법

방법 1

예제에서는 배열을 나타내기 위해 int 유형의 벡터를 정의하고 계산하려는 항목 수보다 크거나 같은 int 유형의 임계값을 정의합니다. 그런 다음 counttheElements 함수를 사용하여 초기 배열과 임계값보다 크거나 같은 요소 수를 생성합니다.

updatetheElement 함수는 배열, 업데이트할 요소의 인덱스, 요소의 새 값을 매개변수로 받아들인 다음 배열의 요소를 업데이트하는 데 사용됩니다. 마지막으로, counttheElements 메소드를 다시 사용하여 수정된 배열과 임계값보다 크거나 같은 요소의 새 개수를 출력합니다.

예 1

으아악

출력

으아악

방법-2

각 쿼리의 기능은 계산입니다. query[i]보다 크거나 같은 배열(항목), 해당 값을 모두 M만큼 감소시키고 업데이트된 배열에서 문제의 나머지 부분을 실행합니다. 입력은 두 개의 배열 array[] 및 query[]이며 크기는 각각 N과 Q입니다.

먼저 배열[]을 오름차순으로 정렬합니다.

l과 같이 첫 번째 위치에서 요소가 query[i]보다 크거나 같은 요소를 찾습니다.

해당 요소가 없으면 응답으로 0을 반환합니다. 그렇지 않으면 응답은 N – l이 됩니다.

最后一步是从提供的范围内的每个元素中减去 M,并将区间 l 中的线段树更改为 N - 1。

示例 2

#include <bits/stdc++.h>
using namespace std;

void build(vector<int>& tosum, vector<int>& a, int l, int r, int rlt){
   if (l == r) {
      tosum[rlt] = a [l - 1];
      return;
   }
   int m = (l + r) >> 1;
   build (tosum, a, l, m, rlt << 1);
   build (tosum, a, m + 1, r, rlt << 1 | 1);
}
void push(vector<int>& tosum, vector<int>& toadd, int rlt, int ln, int rn){
   if (toadd[rlt]) {
      toadd [rlt<< 1] += toadd[rlt];
      toadd [rlt << 1 | 1] += toadd[rlt];
      tosum [rlt<< 1] += toadd[rlt] * ln;
      tosum [rlt << 1 | 1] += toadd[rlt] * rn;
      toadd[rlt] = 0;
   }
}
void update(vector<int>& tosum, vector<int>& toadd, int L, int R, int C, int l,int r, int rlt){
   if (L <= l && r <= R) {
      tosum[rlt] += C * (r - l + 1);
      toadd[rlt] += C;
      return;
   }
   int m = (l + r) >> 1;
   push (tosum, toadd, rlt, m - l + 1,
   r - m);
   if (L <= m)
      update (tosum, toadd, L, R, C, l, m,
      rlt << 1);
   if (R > m)
      update (tosum, toadd, L, R, C, m + 1, r,
      rlt << 1 | 1);
}
int query(vector<int>& tosum,
   vector<int>& toadd,
   int L, int R, int l,
   int r, int rlt){
   if (L <= l && r <= R) {
      return tosum[rlt];
   }
   int m = (l + r) >> 1;
   push (tosum, toadd, rlt, m - l + 1,
   r - m);
   int ans = 0;
   if (L <= m)
   ans += query (tosum, toadd, L, R, l, m,
   rlt << 1);
   if (R > m)
   ans += query (tosum, toadd, L, R, m + 1, r,
   rlt << 1 | 1);
   return ans;
}
void sequMaint(int n, int q,vector<int>& a,vector<int>& b,int m){
   sort(a.begin(), a.end());
   vector<int> tosum, toadd, ans;
   tosum.assign(n << 2, 0);
   toadd.assign(n << 2, 0);
   build (tosum, a, 1, n, 1);
   for (int i = 0; i < q; i++) {
      int l = 1, r = n, pos = -1;
      while (l <= r) {
         int m = (l + r) >> 1;
         if (query (tosum, toadd, m, m, 1, n, 1)
         >= b[i]) {
            r = m - 1;
            pos = m;
         }
         else {
            l = m + 1;
         }
      }
      if (pos == -1)
      ans.push_back(0);
      else {
         ans.push_back(n - pos + 1);
         update (tosum, toadd, pos, n, -m,
         1, n, 1);
      }
   }
   for (int i = 0; i < ans.size(); i++) {
      cout << ans[i] << " ";
   }
}
int main (){
   int A = 4;
   int B = 3;
   int C = 1;
   vector<int> array = {1, 2, 3, 4};
   vector<int> query = {4, 3, 1};
   sequMaint(A, B, array, query, C);
   return 0;
}
로그인 후 복사

输出

1 2 4
로그인 후 복사

结论

综上所述,线段树可以成功地用于计数。数组中大于或等于固定值并进行更新的元素的数量。我们使用惰性传播来更新线段树,而不是更新每个节点。对节点的更新是在延迟传播期间完成的,直到需要为止。总的来说,我们可以有效地数出没有。通过使用具有延迟传播的线段树,数组中大于或等于特定值且发生变化的元素。

위 내용은 주어진 숫자보다 크거나 같은 배열의 요소 수를 쿼리하고 업데이트합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

C 언어 함수에 의해 반환 된 값 유형은 무엇입니까? 반환 값을 결정하는 것은 무엇입니까? C 언어 함수에 의해 반환 된 값 유형은 무엇입니까? 반환 값을 결정하는 것은 무엇입니까? Mar 03, 2025 pm 05:52 PM

이 기사는 기본 (int, float, char 등), 파생 (배열, 포인터, 스트러크) 및 공극 유형을 포함하는 C 함수 리턴 유형에 대해 자세히 설명합니다. 컴파일러는 함수 선언과 반환 명령문을 통해 반환 유형을 결정합니다.

Gulc : C 도서관은 처음부터 구축되었습니다 Gulc : C 도서관은 처음부터 구축되었습니다 Mar 03, 2025 pm 05:46 PM

GULC는 최소 오버 헤드, 공격적인 인라인 및 컴파일러 최적화 우선 순위를 정하는 고성능 C 라이브러리입니다. 고주파 거래 및 임베디드 시스템과 같은 성능 크리티컬 애플리케이션에 이상적 인 디자인은 단순성, 모듈을 강조합니다.

C 언어 기능의 정의 및 호출 규칙은 무엇이며 C 언어 기능의 정의 및 호출 규칙은 무엇이며 Mar 03, 2025 pm 05:53 PM

이 기사는 C 함수 선언 대 정의, 인수 통과 (값 및 포인터 별), 리턴 값 및 메모리 누출 및 유형 불일치와 같은 일반적인 함정을 설명합니다. 모듈성 및 Provi에 대한 선언의 중요성을 강조합니다.

C 언어 함수 형식 문자 케이스 변환 단계 C 언어 함수 형식 문자 케이스 변환 단계 Mar 03, 2025 pm 05:53 PM

이 기사는 문자열 케이스 변환에 대한 C 기능을 자세히 설명합니다. ctype.h의 toupper () 및 tolower ()를 사용하고 문자열을 통한 반복 및 널 터미네이터를 처리합니다. ctype.h를 잊어 버리고 문자 그럴을 수정하는 것과 같은 일반적인 함정은 다음과 같습니다.

메모리에 저장된 C 언어 함수의 반환 값은 어디에 있습니까? 메모리에 저장된 C 언어 함수의 반환 값은 어디에 있습니까? Mar 03, 2025 pm 05:51 PM

이 기사에서는 C 기능 반환 값 저장을 검사합니다. 작은 반환 값은 일반적으로 속도 레지스터에 저장됩니다. 더 큰 값은 포인터에 메모리 (스택 또는 힙)를 사용하여 수명에 영향을 미치고 수동 메모리 관리가 필요할 수 있습니다. 직접 ACC

뚜렷한 사용 및 문구 공유 뚜렷한 사용 및 문구 공유 Mar 03, 2025 pm 05:51 PM

이 기사는 형용사 "별개", 문법 기능, 공통 문구 (예 : "구별", "뚜렷하게 다른") 및 공식 대 비공식의 미묘한 응용 프로그램의 다각적 인 사용을 분석합니다.

STL (정렬, 찾기, 변환 등)의 알고리즘을 효율적으로 사용하려면 어떻게합니까? STL (정렬, 찾기, 변환 등)의 알고리즘을 효율적으로 사용하려면 어떻게합니까? Mar 12, 2025 pm 04:52 PM

이 기사는 효율적인 STL 알고리즘 사용을 자세히 설명합니다. 데이터 구조 선택 (벡터 대 목록), 알고리즘 복잡성 분석 (예 : std :: sort vs. std :: partial_sort), 반복자 사용 및 병렬 실행을 강조합니다. 일반적인 함정과 같은

C 표준 템플릿 라이브러리 (STL)는 어떻게 작동합니까? C 표준 템플릿 라이브러리 (STL)는 어떻게 작동합니까? Mar 12, 2025 pm 04:50 PM

이 기사에서는 컨테이너, 반복자, 알고리즘 및 함수 인 핵심 구성 요소에 중점을 둔 C 표준 템플릿 라이브러리 (STL)에 대해 설명합니다. 일반적인 프로그래밍을 가능하게하기 위해 이러한 상호 작용, 코드 효율성 및 가독성 개선 방법에 대해 자세히 설명합니다.

See all articles