CF1637E Best Pair

Posted solemntee

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1637E Best Pair相关的知识,希望对你有一定的参考价值。


题意:给你一个多重集,求 ( x + y ) × ( c n t x + c n t y ) (x+y)\\times(cnt_x+cnt_y) (x+y)×(cntx+cnty)的最大值,其中 x ! = y x!=y x!=y且有 m m m ( x , y ) (x,y) (x,y)是不能选的
首先枚举 ( x , y ) (x,y) (x,y) O ( N 2 ) O(N^2) O(N2)的,我们考虑枚举 ( c n t x , c n t y ) (cntx,cnty) (cntx,cnty),因为不同的 c n t x cntx cntx O ( N ) O(\\sqrt N) O(N )的,先枚举 ( c n t x , c n t y ) (cnt_x,cnt_y) (cntx,cnty)。对于出现次数为 c n t x cnt_x cntx数量的数字可以从大到小贪心选取。
构建一个优先队列,初始 p u s h ( 1 , 1 ) push(1,1) push(1,1),表示 c n t x cnt_x cntx集合中最大的数和 c n t y cnt_y cnty集合中最大的数。(这个过程和那个轮廓线+优先队列的过程非常像),如果 ( 1 , 1 ) (1,1) (1,1)非法就继续放入 ( 1 , 2 ) 和 ( 2 , 1 ) (1,2)和(2,1) (1,2)(2,1)重复该操作直到找到第一个合法的,就是 c n t x cnt_x cntx c n t y cnt_y cnty的最大值。这样就可以 O ( N + M l o g ( M ) ) O(N+Mlog(M)) O(N+Mlog(M))完成。
其实感觉下来还是很简单写意的,写起来可能稍微有一些细节。
D题太简单就不水了。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct node

    int x,y;
    int val;
    bool operator<(const node &ths)const
    
        return val<ths.val;
    
;
int main()

    int T;
    scanf("%d",&T);
    while(T--)
    
        int n,m;
        scanf("%d%d",&n,&m);
        vector<int>a(n+1);
        map<int,int>mp;
        for(int i=1;i<=n;i++)
        
            scanf("%d",&a[i]);
            mp[a[i]]++;
        
        set<pair<int,int>>bad;
        for(int i=1;i<=m;i++)
        
            int tu,tv;
            scanf("%d%d",&tu,&tv);
            if(tu>tv)swap(tu,tv);
            bad.insert(tu,tv);
        
        for(int i=1;i<=n;i++)bad.insert(a[i],a[i]);

        int N=sqrt(n);
        vector<pair<int,int>>huge;
        vector<vector<int>>small(N+1);
        for(auto [fi,se]:mp)
        
            if(se<N)small[se].push_back(fi);
            else huge.push_back(fi,se);
        
        for(int i=1;i<N;i++)sort(small[i].begin(),small[i].end(),greater<int>());
        ll ans=-1e18;
        for(int size=2;size<=2*N-2;size++)
        
            for(int sizex=1;sizex<min(size,N);sizex++)
            
                int sizey=size-sizex;

                if(sizey<N&&sizex<=sizey)
                
                    int mark1=0,mark2=0;
                    set<pair<int,int>>vis;
                    priority_queue<node>q;
                    if(mark1<small[sizex].size()&&mark2<small[sizey].size())
                    q.push(mark1,mark2,small[sizex][mark1]+small[sizey][mark2]);

                    vis.insert(mark1,mark2);
                    while(!q.empty())
                    
                         auto [x,y,val]=q.top();
                         int tx=small[sizex][x],ty=small[sizey][y];
                         if(tx>ty)swap(tx,ty);
                         if(bad.count(tx,ty))
                         
                            if(x+1<small[sizex].size()&&vis.count(x+1,y)==0)
                            
                                q.push(x+1,y,small[sizex][x+1]+small[sizey][y]);
                                vis.insert(x+1,y);
                            
                            if(y+1<small[sizey].size()&&vis.count(x,y+1)==0)
                            
                                q.push(x,y+1,small[sizex][x]+small[sizey][y+1]);
                                vis.insert(x,y+1);
                            
                         
                         else
                         
                            ans=max(ans,1LL*size*val);
                            break;
                         

                         q.pop();

                    

                
            
        
        for(int i=0;i<huge.size();i++)
        
            for(int j=i+1;j<huge.size();j++)
            
                auto [num1,cnt1]=huge[i];
                auto [num2,cnt2]=huge[j];
                if(bad.count(num1,num2)==0)ans=max(ans,1LL*(1LL*num1+num2)*(1LL*cnt1+cnt2));
            
        
        for(int i=0;i<huge.size();i++)
        
            auto [NUM,cnt]=huge[i];
            for(int j=1;j<N;j++)
            
                for(auto num:small[j])
                

                    if(bad.count(min(num,NUM),max(num,NUM))==0)
                    
                        ans=max(ans,1LL*(1LL*NUM+num)*(1LL*cnt+j));
                        break;
                    
                
            
        
        printf("%lld\\n",ans);


    
    return  0;


以上是关于CF1637E Best Pair的主要内容,如果未能解决你的问题,请参考以下文章

best matched pair

Codeforces Global Round 19 E. Best Pair

Codeforces Global Round 19 E. Best Pair

[CF 827D] Best Edge Wight

cf c(map套pair)

「CF827D Best Edge Weight」 - LCT