On the simple prefix and the differential problem

\ (Part1: \) simple definition of the prefix and the differential

Consider a array \ (A \) , which is a number \ (n-\) key. There \ (m \) times query, query given every two parameters \ (L \) and \ (R & lt \) , required to obtain \ (A [l] + A [l + 1] + ... + A [R & lt] \) .

How to do it?

  • Violence: apparently \ (O (nm) \) of
  • Maintenance data structures: clearly \ (O (mlogn) \) of the
    prefix and the usefulness of this may be that the sequence summing interval problem with \ (O (n + m) \) complexity, in linear time and solve the space.

The prefix and what is it?

In reading \ (A \) array, we pre-array and a prefix \ (S \) , satisfies \ (S [i] = A [1] + A [2] + ... + A [ i] \) . How to quickly calculate \ (S \) ? Apparently \ (S [I] = S [-I. 1] + A [I] \) , \ (S \) arrays can be linear recursion so out.

Then for each query, it \ (A [L] + A [L +. 1] + ... + A [R & lt] = S [R & lt] -S [. 1-L] \) , to achieve a \ (O (n-) \) pretreatment, \ (O (. 1) \) to answer a single query.

So what information can be maintained in such a "prefix" way of doing things? Can be added as long as subtractive i.e. information satisfying the associative law, so can quickly calculate maintenance. For example: fast seek range and rapid product demand interval, and fast seek or the like exclusive interval.

So what difference is it? The difference is the prefix and the inverse operation.

In reading \ (A \) array, we pretreated a differential array \ (T \) , satisfies \ (T [I] = A [I] -A [-I. 1] \) . Differential array is the difference between two adjacent original array.

Consider \ (n-\) items in the array \ (A \) is given \ (m \) times query, query given every three parameters \ (L \) and \ (R & lt \) and \ (D \) requirements for \ (A [l], A [l + 1], ..., A [r] \) were performed \ (+ d \) operations. Finally, find \ (A \) the value of each item of the array.

Using a differential operation, to \ (A [l], A [l + 1], ..., A [r] \) were performed \ (+ d \) operations, is equivalent to the difference data \ (T \ ) for \ (T [l] + = d, T [r + 1] - = d \) operations.

Then directly maintain the differential array \ (T \) , and the difference array is prefixed to restore the original array \ (A \) .

\ (Part2: \) two-dimensional prefix and differential

And many data structures as the prefix and the differential can be extended to two-dimensional matrix.

Prefix and a two-dimensional: \ (S [X] [Y] = S [X] [Y-. 1] + S [. 1-X] [Y] -S [. 1-X] [Y-. 1] + A [X ] [the y-] \) . It is equivalent to a principle of inclusion and exclusion.

Differential dimensional: for \ ((X1, Y1) \) ~ \ ((X2, Y2) \) a \ (A \) array \ (D + \) , is equivalent to \ (T [x1] [y1 ] = D +, T [X1] [Y2 +. 1] - = D, T [+ X2. 1] [Y1] - = D, T [+ X2. 1] [Y2 +. 1] D = + \) . I know \ (T \) reduction \ (A \) to do a two-dimensional prefix and can be.

Prefix and may be two-dimensional / two-dimensional differential, violent split into \ (n-\) one-dimensional prefix and / calculates a dimensional difference.

\ (Part3: \) prefix and simple differentialboardquestion

P1115 largest sub-segment and the
largest sub-segment and is a classic problem, given this linear approach and utilizing the prefix. Pretreatment first array and a prefix \ (S \) .

A sub-segment and \ (A [l] + A [l + 1] + ... + A [r] \) is equivalent to \ (S [R & lt] -S [. 1-L] \) . To make the sub-segments and the maximum sustain \ (S [r] \) is constant, while also such that \ (S [l-1] \) as small as possible. From left to right then the right end enumeration \ (R & lt \) , and maintains all the left \ (S \) is the minimum value \ (mins \) array, subtract the two sub-segment at this time is the maximum, and , try to update the answer.

#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 carpet

Two-dimensional and two-dimensional differential prefix board title. Violence can be split into \ (n \) one-dimensional prefix and / one-dimensional differential maintenance.

#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 undersea high-speed rail

Differential maintenance times with each stretch of road passes, for each stretch of road, remember the number of passes for the \ (S \) , then its minimum cost is \ (min (AS, bs + c) \) . That purchase paper tickets and buy an IC card costs a minimum value. Note that each section of the road start and end of the sequence numbers may need to be adjusted.

#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 borrow classroom

Dichotomous answer \ (x \) , just judge \ (x \) as the answer is legitimate.

How \ (the Check \) ? After comparing the difference with a maintenance situation, and restore the prefix borrowed classrooms to determine whether legal.

#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;
}

Guess you like

Origin www.cnblogs.com/Hakurei-Reimu/p/11621447.html