• [CF1418D] Trash Problem


    Description

    数轴上有 (n) 个点,每次操作你可以将所有位于 (x) 的点移动到 (x+1) 或者 (x-1)。求将所有点移动到不超过两个整点的最小操作次数。现在对点集做出 (q) 次修改,每次添加一个点,或者删除一个点,你需要动态维护答案。

    Solution

    假设任意时刻的点的坐标升序排序后的序列为 ({a_i})

    考虑到答案一定等于 (max a_i - min a_i - max |a_i - a_{i-1}|),我们只需要动态维护最大的相邻点距离就可以了。

    可以维护一个对于所有 (|a_i - a_{i-1}|)multiset,每次暴力插入删除即可

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long 
    const int N = 1000005;
    
    int n,m;
    
    multiset <int> setPos;
    multiset <int> setDelta;
    
    void insert(int x)
    {
        if(setPos.size()==0)
        {
            setPos.insert(x);
        }
        else
        {
            int nSetPosMin=*setPos.begin();
            int nSetPosMax=*setPos.rbegin();
            if(x<=nSetPosMin)
            {
                setDelta.insert(nSetPosMin-x);
            }
            else if(x>=nSetPosMax)
            {
                setDelta.insert(x-nSetPosMax);
            }
            else 
            {
                int nPreVal=*(--setPos.lower_bound(x));
                int nSucVal=*(setPos.lower_bound(x));
                setDelta.erase(setDelta.find(nSucVal-nPreVal));
                setDelta.insert(x-nPreVal);
                setDelta.insert(nSucVal-x);
            }
            setPos.insert(x);
        }  
    }
    
    void erase(int x)
    {
        if(setPos.size()==1)
        {
            setPos.clear();
        }
        else
        {
            auto it=setPos.find(x);
            auto itPre=it,itSuc=it;
            if(it==setPos.begin())
            {
                ++itSuc;
                int nSucVal=*itSuc;
                setDelta.erase(setDelta.find(nSucVal-x));
            }
            else 
            {
                --itPre;
                ++itSuc;
                if(itSuc==setPos.end())
                {
                    int nPreVal=*itPre;
                    setDelta.erase(setDelta.find(x-nPreVal));
                }
                else
                {
                    int nPreVal=*itPre;
                    int nSucVal=*itSuc;
                    setDelta.insert((nSucVal-nPreVal));
                    setDelta.erase(setDelta.find(x-nPreVal));
                    setDelta.erase(setDelta.find(nSucVal-x));
                }
            }
            setPos.erase(setPos.find(x));
        }
    }
    
    void printans()
    {
        if(setDelta.size()==0) cout<<0<<endl;
        else cout<<*setPos.rbegin()-*setPos.begin()-*setDelta.rbegin()<<endl;
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
    
        cin>>n>>m;
    
        for(int i=1;i<=n;i++)
        {
            int x;
            cin>>x;
            insert(x);
        }
        printans();
    
        for(int i=1;i<=m;i++)
        {
            int op,x;
            cin>>op>>x;
            if(op==0)
            {
                erase(x);
            }
            else
            {
                insert(x);
            }
            printans();
        }
        return 0;
    }
    
  • 相关阅读:
    jsp.图书馆
    jsp第七次作业
    jsp第六次作业
    jsp第四次作业
    JSP第二次作业
    软件测试课堂练习
    Android第六次作业
    Android第五次作业
    Android第四次作业
    Android第三次作业
  • 原文地址:https://www.cnblogs.com/mollnn/p/13890982.html
Copyright © 2020-2023  润新知