zoukankan      html  css  js  c++  java
  • uoj386 【UNR #3】鸽子固定器

    link

    (似乎很久没写题解了)

    题意:

    n个物品,每个物品有a,b两个值,给定A,B,现在最多选其中m个,要求最大化选出的物品中【b权值和的B次方-a极差的A次方】。

    $nleq 2 imes 10^5,mleq 50.$

    花絮:

    大概全场最早ac的两人是miaom&wzf2000,用了非标算的“神奇的做法”,太强辣。

    题解:

    按照a排序以后转化为选定一个区间以后最大化区间内部的b权值和。

    然后考虑两种情况:

    • 如果区间长度小于等于m,那么一定是选择连续一段。
    • 否则,区间内部剩余没有选择的物品,它们的b权值一定比选择的都小,否则可以替换获得更优解。

    第一种情况暴力,第二种用链表维护,从小到大删去数,那么每次选择的同样是连续一段。

    时间复杂度$mathcal{O}(nm)$。

    code:

     1 #include<bits/stdc++.h>
     2 #define rep(i,x,y) for (int i=(x);i<=(y);i++)
     3 #define ll long long
     4 #define inf 1000000001
     5 #define y1 y1___
     6 using namespace std;
     7 ll read(){
     8     char ch=getchar();ll x=0;int op=1;
     9     for (;!isdigit(ch);ch=getchar()) if (ch=='-') op=-1;
    10     for (;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
    11     return x*op;
    12 }
    13 #define N 300005
    14 int n,m,A,B,id[N],l[N],r[N];ll ans,a1[N],a2[N],b1[N],b2[N];
    15 struct node{
    16     int a,b;
    17     node(){}
    18     node(int a_,int b_){a=a_,b=b_;}
    19 }q[N];
    20 bool cmp(node x,node y){return x.a<y.a;}
    21 bool cmp2(int x,int y){return q[x].b<q[y].b||q[x].b==q[y].b&&x<y;}
    22 void upd(ll x,ll y){
    23     if (B==2) x=x*x;if (A==2) y=y*y;
    24     ans=max(ans,x-y);
    25 }
    26 int main(){
    27     // freopen("A.in","r",stdin);
    28     // freopen("A.out","w",stdout);
    29     n=read(),m=read(),A=read(),B=read();
    30     rep (i,1,n) q[i].a=read(),q[i].b=read(),id[i]=i,l[i]=i-1,r[i]=i+1;
    31     q[0]=node(0,0);q[n+1]=node(inf,0);
    32     r[0]=1,l[n+1]=n,l[0]=0,r[n+1]=n+1;
    33     sort(&q[1],&q[n+1],cmp);
    34     sort(&id[1],&id[n+1],cmp2);
    35     rep (i,1,n){//区间长度小于等于m
    36         ll sum=0;
    37         for (int j=i;j<=n&&j<=i+m-1;j++){
    38             sum+=q[j].b;
    39             upd(sum,q[j].a-q[i].a);
    40         }
    41     }
    42     rep (i,1,n){//区间长度大于m,从小到大删数
    43         int x=id[i];
    44         b1[0]=q[x].b,b2[0]=0;a1[0]=a2[0]=q[x].a;
    45         for (int j=1,l_=l[x],r_=r[x];j<=m;j++){
    46             b1[j]=b1[j-1]+q[l_].b,b2[j]=b2[j-1]+q[r_].b;
    47             a1[j]=q[l_].a,a2[j]=q[r_].a;
    48             l_=l[l_],r_=r[r_];
    49         }
    50         rep (j,0,m-1) upd(b1[j]+b2[m-j-1],a2[m-j-1]-a1[j]);
    51         r[l[x]]=r[x],l[r[x]]=l[x];
    52     }
    53     cout<<ans<<'
    ';
    54     return 0;
    55 }
    View Code
  • 相关阅读:
    spring Bean的完整生命周期
    idea+maven+ssm搭建boot_crm项目遇到的问题
    面试题:死锁的四个必要条件
    面试题:静态代理和动态代理的区别和联系 没用
    面试题: Struts2
    我所总结的设计模式 合应用场景
    hibernate 对象OID
    hibernate第三天 一对多 , 多对多
    hibernate里的实体类中不能重写toString
    存储前set方法相互关联 只关联了一方 分别set
  • 原文地址:https://www.cnblogs.com/bestFy/p/9309767.html
Copyright © 2011-2022 走看看