[atARC115F]Migration
称$k$个物品的位置$(a_{1},a_{2},...,a_{k})$为一个状态,并设初始状态为$S$,结束状态为$T$
定义状态的比较:首先根据$\sum_{i=1}^{k}h_{a_{i}}$,即代价小的状态更小,在代价相同时字典序小的状态更小
考虑二分答案$mid$,接下来即判定$S$能否在代价恒不超过$mid$的限制下转换为$T$
定义$f(S)$为状态$S$在该限制下所能达到的最小的状态,根据这个转换的传递性以及可逆性,不难发现原条件即等价于$f(S)=f(T)$
将对一个物品极长的连续若干次操作称为一段,那么总存在一种方案,使得$S$在达到$f(S)$的操作过程中,每一段操作都使得$S$严格更小(这段操作前和这段操作后比较)
证明比较简单,如果不满足该条件,将这段操作移动到下一次操作该物品的段之前一定不劣,这样会导致段数减小,因此不能无限操作,即得证
根据这个结论,求$f(S)$即任意执行一段合法(代价仍不超过$mid$)且使得$S$严格变小的操作,并对执行后的这个状态$S'$求$f(S')$即可(根据操作可逆性,有$f(S')=f(S)$)
每一段操作的效果可以看作二元组$(x,y)$,即使得$a_{x}$变为$y$,上面的两个条件分别对应于:
1.合法性,等价于$\Delta h+\sum_{i=1}^{k}h_{a_{i}}\le mid$,其中$\Delta h$为$a_{x}$到$y$路径上(包括端点)最大权值减去$h_{a_{x}}$的值,即判定$a_{x}$移动到最大权值上时代价是否超过$mid$
2.使得$S$严格变小,等价于$h_{y}<h_{a_{x}}$或$h_{y}=h_{a_{x}}$且$y<a_{x}$
根据第2个条件,不难证明一个位置至多被修改$n$次,因此至多$o(nk)$段操作,如果能在$o(\log n)$的复杂度内找到(任意)一段操作,即可做到$o(nk\log^{2}n)$的复杂度(最外层的二分)
可以$o(n^{2})$处理出每一个$k$,当$a_{x}=k$时最小的$\Delta h$,将之记作$H_{k}$,并用set维护出$\min_{x=1}^{n}H_{a_{x}}$以及对应的$x$和$\Delta h$取到$H_{a_{x}}$时的$y$即可找到”最容易实现”的操作(即若该操作不可行则其余操作均不可行)
这样的复杂度仍然不够,考虑优化掉二分,即同时执行求$f(S)$和$f(T)$的过程,每一次操作不需要判定合法性,而是对$ans$取max,选择对$S$或$T$中取的max的值较小的操作先执行,直至$S=T$结束
(关于$S=T$的判定可以记录$S$和$T$中不同的元素个数,以及要特判$S$或$T$已经取到最小了)
这样的做法即在过程中利用单调性实现了二分,做到了$o(nk\log n)$的复杂度
还可以进一步优化,将所有$H_{k}$从小到大排序,并从左到右依次执行,将该位置上所有数都移动到其对应点上,暴力移动复杂度是$o(nk)$的,如果用bitset可以优化到$o(\frac{nk}{\omega})$
然而还有求$H_{k}$的瓶颈,因此复杂度是$o(n^{2}+\frac{nk}{\omega})$
(原题解提到了可以优化到$o(n\log n+k)$,但并没有提到具体方式)


1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 2005
4 #define ll long long
5 struct Edge{
6 int nex,to;
7 }edge[N<<1];
8 priority_queue<pair<int,int> >qS,qT;
9 int E,n,m,x,y,diff,head[N],h[N],S[N],T[N],mx[N],pos[N],H[N];
10 ll sumS,sumT,ans;
11 void add(int x,int y){
12 edge[E].nex=head[x];
13 edge[E].to=y;
14 head[x]=E++;
15 }
16 void dfs(int k,int fa,int sh){
17 sh=max(sh,h[k]);
18 mx[k]=sh;
19 for(int i=head[k];i!=-1;i=edge[i].nex)
20 if (edge[i].to!=fa)dfs(edge[i].to,k,sh);
21 }
22 int main(){
23 scanf("%d",&n);
24 for(int i=1;i<=n;i++)scanf("%d",&h[i]);
25 memset(head,-1,sizeof(head));
26 for(int i=1;i<n;i++){
27 scanf("%d%d",&x,&y);
28 add(x,y);
29 add(y,x);
30 }
31 for(int i=1;i<=n;i++){
32 dfs(i,0,0);
33 H[i]=0x3f3f3f3f;
34 for(int j=1;j<=n;j++)
35 if ((h[j]<h[i])||(h[j]==h[i])&&(j<i)){
36 if (mx[j]-h[i]<H[i]){
37 H[i]=mx[j]-h[i];
38 pos[i]=j;
39 }
40 }
41 }
42 scanf("%d",&m);
43 for(int i=1;i<=m;i++){
44 scanf("%d%d",&S[i],&T[i]);
45 sumS+=h[S[i]],sumT+=h[T[i]];
46 qS.push(make_pair(-H[S[i]],i));
47 qT.push(make_pair(-H[T[i]],i));
48 if (S[i]!=T[i])diff++;
49 }
50 ans=max(sumS,sumT);
51 int tot=0;
52 while (diff){
53 int kS=qS.top().second,kT=qT.top().second;
54 ll ansS=H[S[kS]]+sumS,ansT=H[T[kT]]+sumT;
55 if (!pos[S[kS]])ansS=ansT+1;
56 if (!pos[T[kT]])ansT=ansS+1;
57 ans=max(ans,min(ansS,ansT));
58 if (ansS<ansT){
59 sumS+=h[pos[S[kS]]]-h[S[kS]];
60 diff+=(pos[S[kS]]!=T[kS])-(S[kS]!=T[kS]);
61 qS.pop();
62 S[kS]=pos[S[kS]];
63 qS.push(make_pair(-H[S[kS]],kS));
64 }
65 else{
66 sumT+=h[pos[T[kT]]]-h[T[kT]];
67 diff+=(pos[T[kT]]!=S[kT])-(T[kT]!=S[kT]);
68 qT.pop();
69 T[kT]=pos[T[kT]];
70 qT.push(make_pair(-H[T[kT]],kT));
71 }
72 }
73 printf("%lld",ans);
74 }
[atARC115F]Migration的更多相关文章
- 写给.NET开发者的数据库Migration方案
微软给我们提供了一种非常好用的数据库迁移方案,但是我发现周围的同学用的并不多,所以我还是想把这个方案整理一下..NET选手看过来,特别是还在通过手工执行脚本来迁移数据库的同学们,当然你也可以选择EF的 ...
- EF Core 数据库迁移(Migration)
工具与环境介绍 1.开发环境为vs 2015 2.mysql EF Core支持采用 Pomelo.EntityFrameworkCore.MySql 源代码地址(https://github. ...
- Database first with EntityFramework (Migration)安装和升级
最近看了国外几个项目,发现用EntityFramework做Code First的项目现在很流行. 最让我有兴趣的一个功能则是,EntityFramework对于数据库的安装和升级的无缝完美支持,且很 ...
- Laravel使用笔记 —— migration
在使用 php artisan make:migration 创建migration时,可用 --path 指定创建migration文件的路径, 如果在执行的 php artisan migrate ...
- SVN Server for Migration
SVN Server: http://mxsuse01/svn/repos/erp/Oracle_EMS Report SVN (Put to SVN Sort) 1. *.RDF 2. *CP.LD ...
- ABP Migration(数据库迁移)
今天准备说说EntityFramework 6.0+,它与我之前所学的4.0有所区别,自从4.1发布以来,code first 被许多人所钟爱,Dbcontext API也由此时而生.早在学校的时候就 ...
- migration integer limit option
https://gist.github.com/stream7/1069589 :limit Numeric Type Column Size Max value 1 tinyint 1 byte 1 ...
- MyEclipse Project Migration功能中文简单介绍
前端时间,我对myEclispe的project Migration产生了疑问,也不知道是干啥用的.然后百度之,翻译结果是项目迁移,再次百度其他人对这个的经验,没想到百度到的没多少,甚至都没有说明这个 ...
- 使用 Entity Framework Core 时,通过代码自动 Migration
一 介绍 在使用 Entity Framework Core (下面就叫 EF Core 吧)进行开发时,如果模型有变动,我们要在用 EF Core 提供的命令行工具进行手工迁移,然后再运行程序.但是 ...
随机推荐
- 从零入门 Serverless | SAE 的远程调试和云端联调
作者 | 弈川 阿里巴巴云原生团队 导读:本节课程包含三部分内容,前两个部分简单介绍远程调试以及端云联调的原理,最后在 Serverless 应用引擎中进行实际演示. 经过之前课程的学习,相信大家对于 ...
- Flink Sql 之 Calcite Volcano优化器(源码解析)
Calcite作为大数据领域最常用的SQL解析引擎,支持Flink , hive, kylin , druid等大型项目的sql解析 同时想要深入研究Flink sql源码的话calcite也是必备 ...
- 写了10000条Airtest截图脚本总结出来的截图经验,赶紧收藏!
前言 今天想先给大家分享1个小白用户的Airtest从入门到放弃的故事: 小A是一个自动化的小白,在逛测试论坛的时候,偶然间发现了Airtest这个基于图像识别的UI自动化框架. 出于好奇,小A试用了 ...
- Java:并发笔记-04
Java:并发笔记-04 说明:这是看了 bilibili 上 黑马程序员 的课程 java并发编程 后做的笔记 本章内容-3 线程状态转换 活跃性 Lock 3.10 重新理解线程状态转换 假设有线 ...
- Java:反射小记
Java:反射小记 对 Java 中的 反射,做一个微不足道的小小小小记 概念 Java 反射指的是在 Java 程序运行状态中,对于任何一个类,都可以获得这个类的所有属性和方法:对于给定的一个对象, ...
- [no code][scrum meeting] Beta 2
例会时间:5月14日11:30,主持者:乔玺华 下次例会时间:5月15日11:30,主持者:肖思炀 一.工作汇报 人员 昨日完成任务 明日要完成的任务 乔玺华 - 开issue,分配时间 黎正宇 - ...
- Noip模拟77 2021.10.15
T1 最大或 $T1$因为没有开$1ll$右移给炸掉了,调了一年不知道为啥,最后实在不懂了 换成$pow$就过掉了,但是考场上这题耽误了太多时间,后面的题也就没办法好好打了.... 以后一定要注意右移 ...
- Noip模拟59 2021.9.22
新机房首模拟变倒数 T1 柱状图 关于每一个点可以做出两条斜率分别为$1,-1$的直线, 然后题意转化为移动最少的步数使得所有点都在某一个点的两条直线上 二分出直线的高度,判断条件是尽量让这条直线上部 ...
- Noip模拟36 2021.8.11
刚题的习惯还是改不了,怎么办??? T1 Dove打扑克 考场上打的动态开点线段树+并查集,考后发现自己像一个傻子,并查集就行.. 这几天恶补数据结构疯了 用树状数组维护后缀和,$siz_i$表示编号 ...
- PCB设计中新手和老手都适用的七个基本技巧和策略
本文将讨论新手和老手都适用的七个基本(而且重要的)技巧和策略.只要在设计过程中对这些技巧多加注意,就能减少设计回炉次数.设计时间和总体诊断难点. 技巧一:注重研究制造方法和代工厂化学处理过程 在这个无 ...