BZOJ 2388: Travel planning monotonous block stack and a prefix

title

BZOJ 2388

LUOGU 4192

Description

\ (OIVillage \) is a beautiful scenery of the countryside, in order to make better use of local tourism resources to attract tourists, promote economic development, \ (xkszltl \) decided to build a railway to the local \ (n \) one of the most famous classic connected so that visitors can depart from the railway starting point (No. 1 spot) by train, in order to visit each area. In order to better evaluate the railway, \ (xkszltl \) for each of the resorts have given a oh aesthetics, and aesthetics of the value of a travel route is scenic and it passed. However, with the change of weather and seasons, the aesthetics of some attractions will also change.

\ (xkszltl \) want to provide the best travel guide for each passenger, but due to the limited time visitors may not be able to visit all the attractions, but they do not want to travel too short, so each one hoping to visitors in station within the range end of the journey, and \ (xkszltl \) task is to choose a destination so that the maximum value for their travel route. However, local attractions and sightseeing travelers come is too much, \ (xkszltl \) can not complete tasks in a timely manner, so to find ready to slaughter \ (NOI2011 \) you, I hope you can help him accomplish this difficult task.

Input

The first line gives an integer \ (n-\) , the next line is given \ (n-\) Initial appearance of the resort.

The third line is given an integer \ (m \) , followed \ (m \) lines per instruction behavior:

  1. 0 x y k: Shows a \ (X \) to \ (Y \) the appearance of the edge of this scenic railways plus \ (K \) ;
  2. 1 x y: Indicates a passenger wants to \ (x \) to \ (y \) this (including \ (x \) and \ (y \) ) and get off in a station, you need to tell him the biggest travel value.

Output

For each inquiry, output an integer value representing the maximum travel.

Sample Input

5
1 8 -8 3 -7
3
1 1 5
0 1 3 6
1 2 4

Sample Output

9
22

HINT

Data Limit:

For \ (20 \% \) data, \ (n-, m \ leqslant 3000 \) ;

For \ (40 \% \) data, \ (n-, m \ 30000 leqslant \) ;

For \ (50 \% \) data, \ (n-, m \ 50000 leqslant \) ;

Further \ (20 \% \) data, \ (n-, m \ leqslant 100000 \) , modifying operation \ (\ leqslant 20 \) ;

For \ (100 \% \) data, \ (n-, m \ leqslant 100000 \) .

analysis

The wording on the block, the reference hzwer :

This problem can be divided into blocks.

For the maintenance of a convex hull, a query can be every two minutes.

Modify violence reconstruction of the head and tail, if you add a piece of a value, then the optimal point will not change, because the equivalent of the slope between two points each plus a fixed value.


I think a little bit, I'm still considered \ (BIT \) can write this question, after all maintenance operations convex hull I would write, here is gonna have to think of the (BIT \) \ realize it, goo may fall.

code

#include<bits/stdc++.h>

typedef long long ll;
const int maxn=1e5+10,maxm=350;
const ll INF=1ll<<50;

namespace IO
{
    char buf[1<<15],*fs,*ft;
    inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
    template<typename T>inline void read(T &x)
    {
        x=0;
        T f=1, ch=getchar();
        while (!isdigit(ch) && ch^'-') ch=getchar();
        if (ch=='-') f=-1, ch=getchar();
        while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
        x*=f;
    }

    char Out[1<<24],*fe=Out;
    inline void flush() { fwrite(Out,1,fe-Out,stdout); fe=Out; }
    template<typename T>inline void write(T x,char str)
    {
        if (!x) *fe++=48;
        if (x<0) *fe++='-', x=-x;
        T num=0, ch[20];
        while (x) ch[++num]=x%10+48, x/=10;
        while (num) *fe++=ch[num--];
        *fe++=str;
    }
}

using IO::read;
using IO::write;

template<typename T>inline bool chkMin(T &a,const T &b) { return a>b ? (a=b, true) : false; }
template<typename T>inline bool chkMax(T &a,const T &b) { return a<b ? (a=b, true) : false; }
template<typename T>inline T min(T a,T b) { return a<b ? a : b; }
template<typename T>inline T max(T a,T b) { return a>b ? a : b; }

ll h[maxn],fir[maxm],dif[maxm],add[maxm];//首项、公差
inline double slope(int x,int y)
{
    return (double)(h[y]-h[x])/(y-x);
}

int bel[maxn],n;
int st[maxm],ed[maxm],num[maxn];
inline ll cal(int x)
{
    if (!x || x==n+1) return -INF;
    int t=bel[x];
    return h[x]+fir[t]+dif[t]*(x-st[t])+add[t];
}

int Stack[maxm],top;
int con[maxm][maxm];//凸包
inline void build(int x)
{
    top=0;
    Stack[++top]=st[x];
    for (int i=st[x]+1; i<=ed[x]; ++i)
    {
        while (top>1 && slope(Stack[top-1],Stack[top])<slope(Stack[top-1],i)) --top;
        Stack[++top]=i;
    }
    Stack[0]=0, Stack[top+1]=n+1;
    num[x]=top;
    for (int i=0; i<=top+1; ++i) con[x][i]=Stack[i];
}

inline void pushdown(int x)
{
    ll tmp=fir[x];
    for (int i=st[x]; i<=ed[x]; ++i) h[i]+=tmp, tmp+=dif[x], h[i]+=add[x];
    fir[x]=dif[x]=add[x]=0;
}

inline ll ask(int x)
{
    int l=1, r=num[x];
    ll h1, h2, h3;
    while (l<=r)
    {
        int mid=(l+r)>>1;
        h1=cal(con[x][mid-1]), h2=cal(con[x][mid]), h3=cal(con[x][mid+1]);
        if (h1<h2 && h2<h3) l=mid+1;
        else if (h1>h2 && h2>h3) r=mid-1;
        else return h2;
    }
}

int main()
{
    read(n);
    for (int i=1,x; i<=n; ++i) read(x), h[i]=h[i-1]+x;
    h[0]=h[n+1]=-INF;
    int block=(int)sqrt(n), cnt=0;
    if (n%block) cnt=n/block+1;
    else cnt=n/block;
    for (int i=1; i<=n; ++i) bel[i]=(i-1)/block+1;
    for (int i=1; i<=cnt; ++i) st[i]=(i-1)*block+1, ed[i]=min(n,i*block);
    for (int i=1; i<=cnt; ++i) build(i);
    int m;read(m);
    ll k,ans=0; int l,r;
    for (int i=1,opt,x,y; i<=m; ++i)
    {
        read(opt);read(x);read(y);
        if (!opt)
        {
            read(k);
            l=bel[x], r=bel[y];
            ll tmp=k*(st[l+1]-x+1);
            for (int i=l+1; i<=r-1; ++i) fir[i]+=tmp, dif[i]+=k, tmp+=block*k;
            pushdown(l);
            tmp=k;
            for (int i=x; i<=min(y,ed[l]); ++i) h[i]+=tmp, tmp+=k;
            build(l);
            pushdown(r);
            if (l^r)
            {
                tmp=k*(st[r]-x+1);
                for (int i=st[r]; i<=y; ++i) h[i]+=tmp, tmp+=k;
            }
            tmp=k*(y-x+1);
            for (int i=y+1; i<=ed[r]; ++i) h[i]+=tmp;
            build(r);
            for (int i=r+1; i<=cnt; ++i) add[i]+=tmp;
        }
        else
        {
            l=bel[x], r=bel[y];
            ans=-INF;
            for (int i=l+1; i<r; ++i) chkMax(ans,ask(i));
            for (int i=x; i<=min(y,ed[l]); ++i) chkMax(ans,cal(i));
            if (l^r)
            {
                for (int i=st[r]; i<=y; ++i) chkMax(ans,cal(i));
            }
            write(ans,'\n');
        }
    }
    IO::flush();
    return 0;
}

Guess you like

Origin www.cnblogs.com/G-hsm/p/11445352.html