JZOJ 5703. 【gdoi2018 day2】木板(board)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liyizhixl/article/details/80352671

Description

Description

Input

Input

Output

Output

Sample Input

4 4
1 2 5 6
1 2 4 2
1 1 2
1 3 4
1 1 4
1 1 3

Sample Output

1
2
8
6

Data Constraint

Data Constraint

Solution

  • 这题一开始时以为是数据结构,但是想了很久都没什么想法,结果原来是链表暴力跳!!!

  • 做这题充分利用数据随机这个重要条件!

  • l[i],r[i] 分别表示点 i 向左向右看比自己高的位置在哪儿。

  • 这个可以预处理出来,比如说算 l[i] ,就可以用个指针 j=i1 ,不断比,j=l[j]

  • 不断跳以找到符合条件的 j ,再 l[i]=j

  • 由于数据随机,跳的次数约为 log ,故预处理的复杂度为 O(N log N)

  • 接着我们来处理修改,显然修改横坐标是没用的,直接数组赋值就好了。

  • 而改高度的话,就可能会变动一些 l,r ,我们考虑暴力维护。

  • 现用上述方法重新求出修改点 xl[x],r[x]

  • 比如说我们要重新维护一些点的 r ,那么显然只有第 l[x]x1 个点需要暴力修改。

  • 那还等什么,暴力改呗!由于数据随机,修改的复杂度约为 O(log N)O(log2N)

  • 而改 l 也同理,就是从 x+1r[x] 要暴力修改。

  • 最后就是最重要的询问了。

  • 我们可以利用单调性来解决问题!

  • 设区间为 [x,y] ,那么当沿着 xryl 一直跳,

  • 那么跳出来的点高度一定是先单调上升、再单调下降的。

  • 那么贪心一下,令 l1,r1 分别沿着单调上升、单调下降的点跳,

  • 先保证 l1 的高度不比 r1 高,扫一遍更新答案。

  • 之后再使保证 r1 的高度不比 l1 高,再扫一遍更新答案。

  • 由于数据随机,这些点的数量约为 log 个 ,故查询的复杂度约为 O(log N)

  • 那么总时间复杂度就约为 O(N log N) ,竟轻松通过本题!!!

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
using namespace std;
typedef long long LL;
const int N=5e5+5;
struct data
{
    int x,y;
}a[N];
int l[N],r[N];
inline int read()
{
    int X=0,w=0; char ch=0;
    while(!isdigit(ch)) w|=ch=='-',ch=getchar();
    while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
inline LL max(LL x,LL y)
{
    return x>y?x:y;
}
int main()
{
    freopen("board.in","r",stdin);
    freopen("board.out","w",stdout);
    int n=read(),q=read();
    for(int i=1;i<=n;i++) a[i].x=read();
    for(int i=1;i<=n;i++) a[i].y=read();
    for(int i=1;i<=n;i++)
    {
        int pos=i-1;
        while(pos && a[pos].y<=a[i].y) pos=l[pos];
        l[i]=pos;
    }
    for(int i=n;i;i--)
    {
        int pos=i+1;
        while(pos<=n && a[pos].y<=a[i].y) pos=r[pos];
        r[i]=pos;
    }
    while(q--)
    {
        int ty=read(),x=read(),y=read();
        if(ty==3) a[x].x=y; else
        if(ty==2)
        {
            a[x].y=y;
            int pos=x-1;
            while(pos && a[pos].y<=a[x].y) pos=l[pos];
            l[x]=pos;
            pos=x+1;
            while(pos<=n && a[pos].y<=a[x].y) pos=r[pos];
            r[x]=pos;
            for(int i=x-1;i>=l[x];i--)
            {
                pos=i+1;
                while(pos<=n && a[pos].y<=a[i].y) pos=r[pos];
                r[i]=pos;
            }
            for(int i=x+1;i<=r[x];i++)
            {
                pos=i-1;
                while(pos && a[pos].y<=a[i].y) pos=l[pos];
                l[i]=pos;
            }
        }else
        {
            LL ans=0;
            for(int i=x,j=y;i<=y;i=r[i])
            {
                while(j>i && a[i].y>a[j].y) j=l[j];
                if(j<=i) break;
                ans=max(ans,(LL)(a[j].x-a[i].x)*a[i].y);
            }
            for(int i=y,j=x;i>=x;i=l[i])
            {
                while(j<i && a[i].y>a[j].y) j=r[j];
                if(j>=i) break;
                ans=max(ans,(LL)(a[i].x-a[j].x)*a[i].y);
            }
            printf("%lld\n",ans);
        }
    }
    return 0;
}
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页