首页 > 其他分享 >【20zr提高组十连测day10】信

【20zr提高组十连测day10】信

时间:2024-09-27 13:47:35浏览次数:8  
标签:组十连测 sum 20zr ge day10 define

【20zr提高组十连测day10】信

给定 \(n,m\),\(n,m\le 10^5\),给定分别长度为 \(n-1,m,n,m-1\) 的单调不减的序列 \(A,B,C,D\),然后形如该图建边:

pic1

考虑到序列是递增的,对于除最左上角以外的每个点,每个点一定要选和自己相连的一条边才能形成一棵树。那么选择左边或上边一定是更优的,而且我们发现随便选择左边或上边,最终刚好都能形成一棵树。

这棵生成树就是最优的生成树,它的权值是 \(\sum \min(a_i+b_j,c_{i-1}+d_{j+1})\)。

这样比较丑陋,我们把 \(A,D\) 的标号右移以为,然后钦定 \(a_1=inf,d_1=inf\) 这样不影响正确性。

pic2

答案变成 \(\sum \min(a_i+b_j,c_i+d_j)\)。

如果我们选择第一项,说明 \(a_i+b_j\le c_i+d_j\)

\[ c_i+d_j-a_i-b_j \ge 0\\ (c_i-a_i)+(d_j-b_j)\ge 0\]

那么当 \((c_i-a_i)+(d_j-b_j)<0\) 的时候,我们会选择 \(c_i+d_j\) 这一项。

所以我们的答案式子可以很巧妙地变成:

\[\sum (a_i+b_j)+min(0,(c_i-a_i)+(d_j-b_j)) \]

如果 $(c_i-a_i)+(d_j-b_j)\ge 0 $,答案就取到第一项,否则刚好我们可以取到第二项。

\(a_i+b_j\) 可以 \(O(n+m)\) 算出,后面那部分排个序,然后扫描维护一下指针,也是 \(O(n)\),详见代码。

#include<bits/stdc++.h>
// #define DEBUG
#define sf scanf
#define pf printf
#define int ll
#define rep(x,y,z) for(int x=(y);x<=(z);x++)
using namespace std;
typedef long long ll;
const int N=1e5+5,inf=3e6;
int n,m;
int a[N],b[N],c[N],d[N];
int w1[N],w2[N];
ll s;
ll ans;
signed main(){
    #ifdef DEBUG
    // freopen("ex_A1.in","r",stdin);
    freopen("in.txt","r",stdin);
    freopen("a.out","w",stdout);
    #endif
    sf("%lld%lld",&n,&m);
    rep(i,2,n) sf("%lld",&a[i]);
    rep(i,1,m) sf("%lld",&b[i]);
    rep(i,1,n) sf("%lld",&c[i]);
    rep(i,2,m) sf("%lld",&d[i]);
    a[1]=inf,d[1]=inf;
    ans-=min(a[1]+b[1],c[1]+d[1]);
    rep(i,1,n) ans+=a[i]*m,w1[i]=c[i]-a[i];
    rep(i,1,m) ans+=b[i]*n,w2[i]=d[i]-b[i],s+=w2[i];
    sort(w1+1,w1+n+1);
    sort(w2+1,w2+m+1);
    int r=m;
    rep(i,1,n){
        while(w2[r]+w1[i]>=0&&r>=1) {s-=w2[r];r--;}
        ans+=s+w1[i]*r;
    }
    pf("%lld\n",ans);
}

标签:组十连测,sum,20zr,ge,day10,define
From: https://www.cnblogs.com/liyixin0514/p/18435528

相关文章

  • 【20联赛集训day10】排列
    【20联赛集训day10】排列一个长度为\(n\)的排列,每次操作删除所有存在相邻的数字比它更大的数字,问执行\(k\)次操作后剩下恰好一个数的排列方案数。首先因为每次删除至少删一半的数字,所以最多删\(\log\)次。对于一个排列,我们可以发现把序列按最大值劈开,左右两边互不干扰,成......
  • 【20省选十联测day10】Easy Win
    【20省选十联测day10】EasyWin题意原题链接有\(n\)堆石子,\(n\le5\times10^5\),每堆石子有\(a_i\)个,\(a_i\len\)。Alice和Bob每次可以从,某一堆取至少\(1\)颗、至多\(x\)颗石子,不能取的失败。Alice先手,问对于所有\(1\lex\len\),问谁胜利。思路对于一堆石子,计......
  • 数据处理与统计分析篇-day10-Matplotlib数据可视化
    数据可视化简介可视化介绍数据可视化是指直观展现数据,它是数据处理过程的一部分。把数值绘制出来更方便比较。借助数据可视化,能更直观地理解数据,这是直接查看数据表做不到的数据可视化有助于揭示数据中隐藏的模式,数据分析时可以利用这些模式选择模型可视化库介绍基于......
  • c基础day10
    目录[1]递归函数[2]结构体结构体变量赋值访问重命名结构体数组定义初始化结构体数组的输入输出结构体指针结构体大小共用体枚举存储类型[1]递归函数递推:从原问题出发,按递归公式从未知到已知,最终到达递归终止条件回归:按递归的终止条件求出结果,你想逐步带入......
  • Day10.面向对象编程OOP(2)
    封装该露的露,该藏的藏高内聚,低耦合:高内聚:类的内部数据操作细节自己完成,不允许外部干涉低耦合:仅暴露少量的方法给外部使用提高程序的安全性,保护数据隐藏代码的实现细节统一接口提高系统的可维护性packagecom.dongfang.oop.Demo04;//类publicclassDemo01......
  • C++复习day10
    智能指针为什么需要智能指针?#include<iostream>usingnamespacestd;intdiv(){ inta,b; cin>>a>>b; if(b==0) throwinvalid_argument("除0错误"); returna/b;}voidFunc(){ //1、如果p1这里new抛异常会如何? //2、如果p2这里new抛异常会......
  • day10-配置文件&日志&多线程
    一、配置文件1.1properties配置文件properties配置文件特点:1、都只能是键值对2、键不能重复3、文件后缀一般是.properties结尾的​Properties这是一个Map集合(键值对集合),但是我们一般不会当集合使用主要用来代表属性文件,通过Properties可以读写属性文件里的......
  • 【代码随想录Day10】栈与队列Part01
    232.用栈实现队列题目链接/文章讲解/视频讲解:用栈实现队列classMyQueue{Stack<Integer>stackIn;Stack<Integer>stackOut;publicMyQueue(){stackIn=newStack<>();stackOut=newStack<>();}publicvoidpush(int......
  • day10(IO进程)进程间的通信---共享内存
    目录1.特点2.步骤3.函数接口4.命令1.特点1)共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝。2)为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程将其映射到自己的私有地址空间。进程就可以直接读......
  • 给自己复盘用的tjxt笔记day10
    领取优惠券开发流程页面原型分析,接口统计,数据库设计,生成代码,引入枚举状态接口开发查询发放中的优惠券根据页面原型和接口分析和前端设计的要求,获得四要素@OverridepublicList<CouponVO>queryIssuingCoupons(){//1.查询发放中的优惠券列表List<Coupon>......