zoukankan      html  css  js  c++  java
  • 题解 CF1418D 【Trash Problem】

    (Large exttt{CF1418D})

    前言:

    强烈谴责这套 ( exttt{div.2}) 的翻译(前面ABC更偏),做这套题目时想崩掉,还是读英文题面好。/cy

    题意

    可以参考参考神 ( exttt{Karry5307}) 的翻译,十分得清晰, 这里不多做赘述。

    思路

    其实思路十分显然,对于两颗木桩坐标为 (x_1) , (x_2)产生的总花费,分三种情况讨论:

    • 显然左边的木桩左边的点全到左边的木桩,花费为 (x1-min_x)

    • 显然右边的木桩右边的点全到右边的木桩,花费为 (max_x-x_2)

    • 中间的点离哪棵木桩近就去哪,但是有一点十分重要,中间的木桩花费的最优情况肯定是分成两部分,左边到左边的木桩,右边到右边的木桩,令这两部分零界的点分别为 (x_3) , (x_4),产生的花费为 ((x_3-x_1)+(x_2-x_4))

    花费全加起来,你会恍然大悟地发现,花费为 ((max_x-min_x)-(x_3-x_2)) ( (x_2)(x_3) 之间没有其它点)。

    在每个状态下,(max_x)(min_x) 是一定的,要让花费最小,问题就变成了动态维护区间中任意两点之间最远的距离

    题解区一群大佬用了蒟蒻我不会的科技轻松A掉了,于是蒟蒻我只好用大码量的线段树解决(vp时出现了一个小错误导致没有绝杀QwQ) 。

    线段树维护三个值,区间内最长的两点间的距离,区间内最左边的点的位置,区间内最右边的点的位置。

    你会发现顺便把动态维护最大值和最小值给做掉了,但是我原本还弄了个查询操作QwQ

    具体的 (up) 操作请见代码

    代码

    (4.99s) 最优解第一

    #include <bits/stdc++.h>
    using namespace std;
    
    #define ls n << 1
    #define rs n << 1 | 1
    const int N = 2e5;
    inline int read()
    {
        register int s = 0;
        register bool neg = 0;
        register char c = getchar();
        for (; c < '0' || c > '9'; c = getchar())
            neg |= (c == '-');
        for (; c >= '0' && c <= '9'; s = s * 10 + (c ^ 48), c = getchar())
            ;
        return (neg ? -s : s);
    }
    
    int a,b,q[N+10],p[N+10],top;
    bool t[N+10];
    struct node {
        int l,r,lmx,rmx,sum;
    }s[N*4+10];
    struct ask {
        int opt,x;
    }ask[N+10];
    
    inline void up(int n) {
        s[n].lmx=((s[ls].lmx==-1)?s[rs].lmx:s[ls].lmx);//区间内端点只有一个的时候将左端点和右端点赋值一样,方便操作。
        s[n].rmx=((s[rs].rmx==-1)?s[ls].rmx:s[rs].rmx);
        s[n].sum=max(max(s[ls].sum,s[rs].sum),s[ls].rmx!=-1&&s[rs].lmx!=-1?s[rs].lmx-s[ls].rmx:0);//注意左区间的右端点到有区间的左端点也要被统计在内
    }
    
    inline void build(int n,int l,int r) {
        s[n].l=l;
        s[n].r=r;
        s[n].sum=0;
        s[n].lmx=-1;
        s[n].rmx=-1;
        if(l==r) {
            if(t[l]) s[n].lmx=s[n].rmx=p[l];
            return;
        }
        int mid=(l+r)>>1;
        build(ls,l,mid);
        build(rs,mid+1,r);
        up(n);
    }
    
    inline void insert(int n,int k) {
        if(s[n].l==s[n].r) {
            s[n].lmx=s[n].rmx=p[k];
            return;
        }
        int mid=(s[n].l+s[n].r)>>1;
        if(k<=mid) insert(ls,k);
        else insert(rs,k);
        up(n);
    }
    
    inline void del(int n,int k) {
        if(s[n].l==s[n].r) {
            s[n].lmx=s[n].rmx=-1;
            return;
        }
        int mid=(s[n].l+s[n].r)>>1;
        if(k<=mid) del(ls,k);
        else del(rs,k);
        up(n);
    }
    
    signed main()
    {
        // freopen("in1.in","r",stdin);
        a=read();
        b=read();
        top=0;
        for(int i=1;i<=a;i++){
            q[i]=p[++top]=read();
        }
        for(int i=1;i<=b;i++) {
            ask[i].opt=read();
            ask[i].x=p[++top]=read();
        }
        sort(p+1,p+top+1);
        top=unique(p+1,p+top+1)-p-1;
        for(int i=1;i<=a;i++) t[lower_bound(p+1,p+top+1,q[i])-p]=1;
        build(1,1,top);
        printf("%d
    ",s[1].rmx-s[1].lmx-s[1].sum);
        for(int i=1;i<=b;i++) {
            if(ask[i].opt==1)
                insert(1,lower_bound(p+1,p+top+1,ask[i].x)-p);
            else
                del(1,lower_bound(p+1,p+top+1,ask[i].x)-p);
            printf("%d
    ",s[1].rmx-s[1].lmx-s[1].sum);
        }
        return 0;
    }
    

    十分遗憾的一题QwQ

  • 相关阅读:
    flutter常用内置动画组件
    flutter中的生命周期函数
    Flutter打开第三方应用
    在windows系统搭建并运行一个Flutter项目
    在windows系统搭建Flutter开发环境
    axios的get请求无法设置Content-Type
    解决vue中使用laydate.js选择日期后再修改其他model时日期会被清空问题
    Git commit时提示错误时    解决办法
    CSS3 @font-face属性
    解决webstorm本地IP访问页面出错的问题
  • 原文地址:https://www.cnblogs.com/RedreamMer/p/13904275.html
Copyright © 2011-2022 走看看