연구 # 번호 모 블록 팀 노트

도입

모 팀의 전형적인 예 : 로스 작은 계곡 P2709 조회 B
리틀 B는 $ N은 $ K $에 $ 1 $를 $ 사이의 정수를 포함하는 순서가있다. 그는 $ \ limits_ 추구 $ M $ 총 각 질문 소정 간격 $의 [의 L, R] $를 묻는다 {I = 1} ^ {K} 값 \ 합은 C_I ^ 2 개 $ 여기서 $ $ C_I 이는 I $에서 $ $ [L, R] $의 반복 수를 나타낸다. 작은 B는 그 문제에 대한 해답을 얻을 수 있도록 부탁드립니다.

생각

방법 1

당신이 얼마나 잘 직접적인 폭력에 대해 어떻게 생각
$에 $ L $에서 모든 스윕을 R은 $
바람직 스코어는 0

방법 2

L과 R은 두 개의 포인터를 설정, 두 사람은 다시 재 청소를 요구
하지만, L과 R 포인터를 하나의 그리드는 과거에 이동
훨씬 더되지만 두 번 L과 R 사이에 요구한다면, 지금,이, 잘못된 알고리즘
의 효율성을 방법은 아니다

모 팀

모 팀은 아름다운 알고리즘 폭력, 일반 모의 복잡성의 최악의 팀이다 $ n \ SQRT N $
이미 가장 이상한 질문을 처리 할 수있는
부분 블록을 기반으로 그것을 수행하는 방법, 우리는 오프라인 처리 간격 요청을 정렬
ㄱ 동일한 눌러 내 우단 행 개의 질의 지점을 떠나는 경우
왼쪽 지점은 동일한 블록 좌단 행에 있지 않으면
다음 방법 바인딩,이 포인터 $의 움직임의 복잡성 n \ SQRT N $가 발견 된
아래 밖으로아니엄격한 증명 :
좌단 포인트 $ \ SQRT n 개의 $까지 블록 내에서 이동되어, $까지 $ N 배에 블록을 이동
외측 $의 \의 이동을 차단 SQRT N $ 배까지 $ N $ 위로 이동, 두 지점 좌측 블록의 외측
오른쪽 $ N $의 총 포인트가 이동 SQRT N $ 차단 $ \ 총
오른쪽 점 이동 $ N $ 블록 중 대부분은 외부 빠른 이동 최대 $ \ SQRT N $ 시간 후에
덜 복잡하다 $ n \ SQRT N $ A

AC 코드

#include<bits/stdc++.h>
using namespace std;
int n,m,k,K,cnt[50010],a[50010],ans[50010],to[50010];
struct node
{
    int id,l,r;
    void init(int i){id=i,scanf("%d%d",&l,&r);}
    bool operator<(const node&a)const
        {return to[l]==to[a.l]?(to[l]&1?r<a.r:r>a.r):l<a.l;}
}q[50010];
int main()
{
    scanf("%d%d%d",&n,&m,&k),K=sqrt(n);
    for(int i=1;i<=n;i++)to[i]=(i-1)/K+1;
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=1;i<=m;i++)q[i].init(i);
    sort(q+1,q+m+1);
    int l=1,r=0,res=0;
    for(int i=1;i<=m;i++)
    {
        while(r<q[i].r)cnt[a[++r]]++,res+=2*cnt[a[r]]-1;
        while(l>q[i].l)cnt[a[--l]]++,res+=2*cnt[a[l]]-1;
        while(l<q[i].l)cnt[a[l]]--,res-=2*cnt[a[l++]]+1;
        while(r>q[i].r)cnt[a[r]]--,res-=2*cnt[a[r--]]+1;
        ans[q[i].id]=res;
    }
    for(int i=1;i<=m;i++)printf("%d\n",ans[i]);
    return 0;
}

추천

출처www.cnblogs.com/muronglin/p/fenkuai-modui.html