zoukankan      html  css  js  c++  java
  • [at4631]Jewels

    如果要选某颜色,必然会选该颜色最大的两个,那么不妨将这两个宝石权值修改为两者的平均数,显然不影响两者的和,也即不影响答案

    接下来,将所有宝石按权值从大到小排序,并在权值相同时按颜色编号从小到大(使颜色相同的在一起)

    此时,如果可以选前$i$个宝石,那么显然直接选即可

    否则,注由于每种颜色权值最大的两个宝石权值(和颜色)都相同,那么必然是相邻的,因此不能选的原因必然是第$i$个宝石的颜色在之前没有出现过

    接下来,考虑先选前$i-1$个宝石,然后进行调整:

    1.选择$i$之后(包括$i$)权值最大且该颜色之前选过的宝石

    2.选择$i$之后(包括$i$)权值最大且颜色相同的两个宝石,并删除$i-1$之前(包括$i-1$)权值最小且该颜色选过不小于3次的宝石

    3.选择$i$之后(包括$i$)权值最大且颜色相同的三个宝石,并删除$i-1$之前(包括$i-1$)权值最小且颜色相同的两个宝石

    由于前面的宝石权值不小于后面,不难证明不会删更多的宝石,因此只有这三种情况,用set维护即可

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 200005
     4 #define ll long long
     5 vector<int>a[N];
     6 pair<int,int>b[N];
     7 multiset<int>S01,S11;
     8 multiset<ll>S02,S12,S13;
     9 int n,m,x,y,nn,vis[N];
    10 ll sum,ans;
    11 bool cmp(int x,int y){
    12     return x>y;
    13 }
    14 int main(){
    15     scanf("%d%d",&n,&m);
    16     for(int i=1;i<=n;i++){
    17         scanf("%d%d",&x,&y);
    18         a[x].push_back((y<<1));
    19     }
    20     for(int i=1;i<=m;i++){
    21         sort(a[i].begin(),a[i].end(),cmp);
    22         if (a[i].size()){
    23             y=(a[i][0]>>1)+(a[i][1]>>1);
    24             a[i][0]=a[i][1]=y;
    25             S12.insert(0LL+y+y);
    26             if (a[i].size()>=3)S13.insert(0LL+y+y+a[i][2]);
    27         }
    28         for(int j=0;j<a[i].size();j++)b[++nn]=make_pair(-a[i][j],i);
    29     }
    30     sort(b+1,b+nn+1);
    31     for(int i=1;i<=n;i++){
    32         x=b[i].second;
    33         if (vis[x]){
    34             if (vis[x]>=2)S01.insert(a[x][vis[x]]);
    35             if (vis[x]==1)S02.insert(0LL+a[x][vis[x]-1]+a[x][vis[x]]);
    36             printf("%lld
    ",(sum+a[x][vis[x]])/2);
    37         }
    38         else{
    39             ans=-1e18;
    40             if (!S11.empty())ans=(*--S11.end());
    41             if ((!S01.empty())&&(!S12.empty()))ans=max(ans,(*--S12.end())-(*S01.begin()));
    42             if ((!S02.empty())&&(!S13.empty()))ans=max(ans,(*--S13.end())-(*S02.begin()));
    43             if (ans+sum<0)printf("-1
    ");
    44             else printf("%lld
    ",(ans+sum)/2);
    45         }
    46         if (vis[x])S11.erase(S11.find(a[x][vis[x]]));
    47         if (vis[x]+1<a[x].size())S12.erase(S12.find(0LL+a[x][vis[x]]+a[x][vis[x]+1]));
    48         if (vis[x]+2<a[x].size())S13.erase(S13.find(0LL+a[x][vis[x]]+a[x][vis[x]+1]+a[x][vis[x]+2]));
    49         sum+=a[x][vis[x]++];
    50         if (vis[x]<a[x].size())S11.insert(a[x][vis[x]]);
    51         if (vis[x]+1<a[x].size())S12.insert(0LL+a[x][vis[x]]+a[x][vis[x]+1]);
    52         if (vis[x]+2<a[x].size())S13.insert(0LL+a[x][vis[x]]+a[x][vis[x]+1]+a[x][vis[x]+2]);
    53     }
    54 }
    View Code
  • 相关阅读:
    js学习之函数
    面试题
    渐进增强(progressive enhancement)、优雅降级(graceful degradation)
    倒计时
    css 平行四边形
    网址URL分解
    图片延时加载
    获取元素的宽高,左边距上边距
    电商平台放大镜效果
    js笔记
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15011718.html
Copyright © 2011-2022 走看看