• 【CF392D】Three Arrays-set+multiset


    测试地址:Three Arrays
    题目大意:有三个长为n的数列A,B,C,要求从A中取前a个数,从B中取前b个数,从C中取前c个数,使得取出的数的并集和这三个数列的并集相等,求最小的a+b+c
    做法:本题需要用到set+multiset。
    这题也是清北学堂讲的,思想非常不错,写在这里跟大家分享。
    考虑只有两个数列怎么做,先预处理出fa(i),fb(i),表示iAB中最早出现的位置。我们可以从大到小枚举aa越小,对b的限制越多,每个限制都形如bfb(i)这种形式,这样我们可以O(n)求出。
    那么现在有三个数列,我们又要怎么做呢?也是考虑从大到小枚举aa越小,对b,c的限制越多,每个限制都形如:bfb(i)cfc(i)。以b,c为横纵坐标建平面直角坐标系,将限制映射到坐标系上,我们发现这其实就是将点(fb(i),fc(i))左下的区域全部挖去。那么此时我们怎么找最小的b+c呢?观察发现,我们挖掉不能取的那些区域后,剩下的区域有很多向左下凸出来的拐角,那么最小的b+c必定在这些拐角中的一个取得。所以我们现在的目标就是维护这个阶梯形状的东西。
    考虑维护组成阶梯形的那些限制。随着a的变小,对b,c的限制不断增多,也就是不断挖掉新的区域,有时我们会发现新的区域包含了一些旧的区域,这时候旧的区域就没有必要存下来了,我们就删除这个限制。又因为一个区域最多加入一次、删除一次,一共有不超过3n个区域,用set维护的话,就可以做到O(nlogn)的复杂度了。同时再用一个multiset来维护拐角上b+c的所有可能取值即可。
    以下是本人代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int inf=1000000000;
    int n,a[100010],b[100010],c[100010],tot;
    int fa[300010]={0},fb[300010]={0},fc[300010]={0};
    struct forsort
    {
        int val,id1,id2;
    }f[300010];
    struct Pair
    {
        int b,c;
    };
    bool operator < (Pair a,Pair b) {return a.b<b.b;}
    set<Pair> s;
    set<Pair>::iterator it;
    multiset<int> vals;
    multiset<int>::iterator valit;
    
    bool cmp(forsort a,forsort b)
    {
        return a.val<b.val;
    }
    
    void init()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&f[++tot].val);
            f[tot].id1=1,f[tot].id2=i;
        }
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&f[++tot].val);
            f[tot].id1=2,f[tot].id2=i;
        }
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&f[++tot].val);
            f[tot].id1=3,f[tot].id2=i;
        }
    
        sort(f+1,f+3*n+1,cmp);
        tot=0;
        for(int i=1;i<=3*n;i++)
        {
            if (i==1||f[i].val!=f[i-1].val) tot++;
            if (f[i].id1==1) a[f[i].id2]=tot;
            if (f[i].id1==2) b[f[i].id2]=tot;
            if (f[i].id1==3) c[f[i].id2]=tot;
        }
    
        for(int i=1;i<=n;i++)
            if (!fa[a[i]]) fa[a[i]]=i;
        for(int i=1;i<=n;i++)
            if (!fb[b[i]]) fb[b[i]]=i;
        for(int i=1;i<=n;i++)
            if (!fc[c[i]]) fc[c[i]]=i;
    }
    
    void insertPair(int newb,int newc)
    {
        int nowb,nowc;
        Pair e={newb,newc};
        it=s.upper_bound(e);
        if ((*it).c>=e.c) return;
        nowc=(*it).c;
        it--;
        valit=vals.find((*it).b+nowc);
        vals.erase(valit);
        while((*it).c<=e.c)
        {
            nowb=(*it).b,nowc=(*it).c;
            it--;
            vals.erase((*it).b+nowc);
            it++;
            s.erase(it);
            it=s.lower_bound(e);
            it--;
        }
        nowb=(*it).b,nowc=(*it).c;
        vals.insert(nowb+e.c);
        it++;
        nowc=(*it).c;
        vals.insert(e.b+nowc);
        s.insert(e);
    }
    
    void work()
    {
        Pair e;
        e.b=0,e.c=inf+1;
        s.insert(e);
        e.b=inf+1,e.c=0;
        s.insert(e);
        vals.insert(0);
        for(int i=1;i<=tot;i++)
            if (!fa[i]) insertPair(fb[i]?fb[i]:inf,fc[i]?fc[i]:inf);
        int ans=inf;
        bool flag=1;
        for(int i=n;i>=1;i--)
        {
            ans=min(ans,i+(*vals.begin()));
            if (fa[a[i]]==i)
            {
                if (!fb[a[i]]&&!fc[a[i]]) {flag=0;break;}
                insertPair(fb[a[i]]?fb[a[i]]:inf,fc[a[i]]?fc[a[i]]:inf);
            }
        }
        if (flag) ans=min(ans,(*vals.begin()));
        printf("%d",ans);
    }
    
    int main()
    {
        init();
        work();
    
        return 0;
    }
  • 相关阅读:
    [SSRS] Use Enum values in filter expressions Dynamics 365 Finance and Operation
    Power shell deploy all SSRS report d365 FO
    display method in Dynamics 365 FO
    How To Debug Dynamics 365 Finance and Operation
    Computed columns and virtual fields in data entities Dynamics 365
    Azure DevOps for Power Platform Build Pipeline
    Create readonly entities that expose financial dimensions Dynamics 365
    Dataentity call stack dynamics 365
    Dynamics 365 FO extension
    Use singletenant servertoserver authentication PowerApps
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793465.html
Copyright © 2020-2023  润新知