간단한 접두사와 차동 문제에

\ (파트 1 : \) 접두어 차동 간단한 정의

어레이 고려 \ (A \) 의 수이고, \ N- (\) 키. 거기 \ (m의 \) 마다 두 개의 파라미터 주어진 시간 질의, 질의 \ (L의 \)\ (R & LT \) 받아야, \ (A [1] + A [1 + 1] + ... + A [R & LT] \) .

그것을 어떻게?

  • 폭력 : 분명히 \ (O (㎚) \)
  • 유지 보수 데이터 구조 : 명확 \ (O (mlogn) \)
    프리픽스 및 유용성이있을 수 있다는 간격 합산 시퀀스 에 문제 \ (O (N + m) \) 의 복잡성이 선형 시간 과 공간을 해결한다.

접두사 그것은 무엇인가?

읽기에서 \ (A \) 어레이, 우리는와 프리픽스 어레이 미리 \ (S \) , 만족 \ (S가 [I] = A [1] + A [2] + ... + A [ I] \) . 얼마나 빨리 계산하는 \ (S \)를 ? 명백하게 \ (S [I] =에서 S [-I. 1] + A [I]가 \) \ (S \) 배열 선형 재귀 그렇게 아웃 할 수있다.

각 질의는 대 \ (A [L] + A [L의 +. 1] + ... + A [R & LT =에서 S [R & LT] -S [. 1-L] \) 하는 얻기 (\를 O (N-) \) 전처리, \ (O (. 1) \) 에 응답 할 수있는 단일 쿼리.

그래서 정보는 일을 같은 "접두사"방식으로 유지 될 수있다? 감산 즉, 정보가 결합 법칙을 만족하는, 이렇게 빨리 유지 보수를 계산할 수만큼 추가 할 수 있습니다. 예를 들어 : 빠른 범위와 빠른 제품 수요 간격을 추구, 빠른 추구 등 독점 간격.

그래서 무슨 차이? 차이는 프리픽스 및 역 동작이다.

읽기에서 \ (A \) 어레이, 우리는 차동 배열 전처리 \를 (T \)는 , 만족 \ (T [I]는 = A [I] -A [-I. 1] \) . 차동 어레이는 두 개의 인접한 어레이 사이의 원래의 차이이다.

고려 (\ N-) \ 배열 항목 \ (A \) 주어진 \ (m의 \) 번 쿼리는 쿼리마다 세 개의 매개 변수를 부여 \ (L의 \)\ (R & LT \)\ (D \) 요구 \ (A [1]하는 [L + 1], ..., A [R]를 \) 수행 하였다 (\ + D \) 작업. 마지막으로, 검색 (A \) \ 어레이의 각 항목의 값.

위하여, 차동 동작을 이용 \ (A [1]을하는 [L + 1], ..., A [R]를 \) 수행 하였다 (\ + D \) 동작, 차분 데이터에 상당 \ (T \ ) 에 대한 \ (T [1] + = D, T [R + 1] - = D의 \) 동작.

이어서 직접 차동 배열 유지 \ (T \)를 , 차분 어레이 원의 배열을 복원 접두어 \ (A \) .

\ (파트 2 : \) 이차원 프리픽스 차동

그리고 프리픽스 차동 많은 데이터 구조는 이차원 행렬로 확장 될 수있다.

프리픽스와 이차원 : \ (S [X] [Y] =에서 S [X]. Y- 1] + S [. 1-X]가 [Y]가 -S [. 1-X]. Y- 1] + A [X [Y-] \) . 그것은 포함과 배제의 원리에 해당합니다.

차원 차등위한 \ ((X1, Y1) \) ~ (\ (X2, Y2) \) \ (A \) 배열 \ (D + \)은 , 동등 \ (T [X1] [Y1 ] [. Y2의 + 1] = D +, T [X1] - = D, T [+ X2 1이다.] [Y1] - [. Y2의 + 1] = D, T [. + X2 1] D = + \) . 나는 알고있다 \ (T \) 감소 \ (A \)는 이차원 접두사를 수행 할 수 있습니다.

프리픽스와 이차원 / 이차원 차동로 분할 될 수 폭력적 \ (\ N-) 일차원 접두어 및 /은 치수 차를 산출한다.

\ (파트 3 : \) 접두사와 간단한 차동이름

P1115 큰 서브 세그먼트 및
최대 서브 세그먼트는이 선형 방식 및 접두사를 사용하는 소정의 고전적인 문제이다. 전처리 제 배열 프리픽스 \ (S \) .

서브 세그먼트 \ (A [1] + A [1 + 1] + ... + A [R] \) 와 동등하다 (\ S [R & LT] -S [. 1-L] \) . 서브 세그먼트를 확인하고, 최대 유지 \을 (S [R] \) , 일정하게하면서 또한 그 \ (S [L-1] \) 가능한 한 작게. 바로 그때에 우단 열거 왼쪽부터 \ (R & 중위 \)를 , 및 유지 모두 왼쪽의 \ (S는 \) 최소값이다 \ (분 \) 배열 최대이고,이 때의 두 개의 서브 - 세그먼트를 빼기 및 대답을 업데이트하려고합니다.

#include<bits/stdc++.h>//P1115 最大子段和
using namespace std;
#define re register
#define ll long long
#define il inline
#define dou double
#define un unsigned
il int read()
{
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
#define INF 114514114
#define clr(x) memset(x,0,sizeof(x))
#define N 200000+10
int n,ans=-INF;
int a[N],s[N],mins[N];
int main()
{
    n=read();
    for(re int i=1;i<=n;i++)mins[i]=INF;
    for(re int i=1;i<=n;i++)
    {
        a[i]=read();
        s[i]=s[i-1]+a[i];
        mins[i]=min(mins[i-1],s[i]);
    }
    for(re int r=1;r<=n;r++)
        ans=max(ans,s[r]-mins[r-1]);
    cout<<ans<<endl;
    return 0;
}

P3397 카펫

두 차원 및 2 차원 차동 접두사 보드 제목입니다. 폭력으로 분할 될 수있다 (\ n \) 일차원 접두어 및 / 일차원 차등 유지.

#include<bits/stdc++.h>//P3397 地毯
using namespace std;
#define re register
#define ll long long
#define il inline
#define dou double
#define un unsigned
il int read()
{
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
#define INF 114514114
#define clr(x) memset(x,0,sizeof(x))
#define N 1000+10
int n,m,a,b,c,d;
int tag[N][N],sum[N][N];
int main()
{
    n=read();m=read();
    for(re int i=1;i<=m;i++)
    {
        a=read();b=read();c=read();d=read();
        for(re int j=a;j<=c;j++)
        {
            tag[j][b]++;
            tag[j][d+1]--;
        }
    }
    for(re int i=1;i<=n;i++)
    {
        for(re int j=1;j<=n;j++)
        {
            sum[i][j]=sum[i][j-1]+tag[i][j];
            printf("%d ",sum[i][j]);
        }
        printf("\n");
    }
    return 0;
}

P3406 해저 고속철도

도 패스마다 스트레칭 차등 유지 시간은,도 각 스트레치 들면 대해 패스의 수를 기억 \ (S \) 다음, 최소 비용이다 \ ((최소 AS, BS + c) \) . 즉, 구매 종이 티켓과는 IC 카드가 최소 값을 비용을 구입할 수 있습니다. 일련 번호의 도로 시작과 끝의 각 부분을 조정해야 할 수도 있습니다.

#include<bits/stdc++.h>//P3406 海底高铁
using namespace std;
#define re register
#define ll long long
#define il inline
#define dou double
#define un unsigned
il int read()
{
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
#define INF 114514114
#define clr(x) memset(x,0,sizeof(x))
#define N 100000+10
#define M 100000+10
ll n,m,ans;
ll p[M],a[N],b[N],c[N],tag[N],s[N];
int main()
{
    n=read();m=read();
    for(re int i=1;i<=m;i++)p[i]=read();
    for(re int i=1;i<=n-1;i++)
    {
        a[i]=read();b[i]=read();c[i]=read();
    }
    for(re int i=1;i<=m-1;i++)
    {
        if(p[i]<p[i+1])
        {
            tag[p[i]]++;
            tag[p[i+1]]--;
        }
        else
        {
            tag[p[i+1]]++;
            tag[p[i]]--;
        }
    }
    for(re int i=1;i<=n;i++)s[i]=s[i-1]+tag[i];
    for(re int i=1;i<=n;i++)
        ans=ans+min(a[i]*s[i],b[i]*s[i]+c[i]);
    cout<<ans<<endl;
    return 0;
}

P1083 대출 교실

양분 응답 \ (X의 \) , 단지 판단 \ (X \) 대답은 합법적으로.

어떻게 \ (점검 \) ? 접두사 빌려 교실을 유지 보수 상황의 차이를 비교하고, 복원 한 후 법적 여부를 확인합니다.

#include<bits/stdc++.h>
using namespace std;
#define re register
#define ll long long
#define il inline
#define dou double
#define un unsigned
il int read()
{
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
#define N 1000000+10
#define M 1000000+10
#define clr(x) memset(x,0,sizeof(x))
int n,m;
int a[N],d[M],s[M],t[M],tag[N],sum[N];
il bool check(int x)
{
    clr(tag);clr(sum);
    for(re int i=1;i<=x;i++)
    {
        tag[s[i]]+=d[i];
        tag[t[i]+1]-=d[i];
    }
    for(re int i=1;i<=n;i++)
    {
        sum[i]=sum[i-1]+tag[i];
        if(sum[i]>a[i])
            return false;
    }
    return true;
}
int main()
{
    n=read();m=read();
    for(re int i=1;i<=n;i++)
        a[i]=read();
    for(re int i=1;i<=m;i++)
    {
        d[i]=read();s[i]=read();t[i]=read();
    }
    int l=1,r=m;
    if(check(m))
    {
        cout<<0<<endl;
        return 0;
    }
    while(l<r)
    {
        int mid=(l+r)>>1;
        if(check(mid))
            l=mid+1;
        else
            r=mid;
    }
    cout<<-1<<endl<<l<<endl;
    return 0;
}

추천

출처www.cnblogs.com/Hakurei-Reimu/p/11621447.html