首先暴力dp,令$f_{i,j}$表示前$i$个点划分为$j$段,即有转移$f_{i,j}=\min f_{k-1,j-1}+calc(k,i)$(其中$calc(i,j)$表示求区间$[i,j]$的顺序对数)

可以先枚举$j$,记$g_{i}=f_{i,j-1}$,则$f_{i}=\min g_{k-1}+calc(k,i)$,先$o(k)$枚举以下层数,快速支持上述转移

令$mn_{i}$为取到最小值的最小的$k$,即有$f_{i}=g_{mn_{i}-1}+calc(mn_{i},i)$,则有$mn_{i}\le mn_{i+1}$(即决策单调性),证明如下:

反证法,若$mn_{i}>mn_{i+1}$(为方便表示,以下记$x=mn_{i}$、$y=mn_{i+1}$),则由于其都是最小的转移,则有:$g_{x-1}+calc(x,i)\le g_{y-1}+calc(y,i)$,$g_{x-1}+calc(x,i+1)\ge g_{y-1}+calc(y,i+1)$

将第二个式子乘上-1后与第一个式子分别相加,可得$calc(x,i)-calc(x,i+1)\le calc(y)-calc(y,i+1)$

考虑顺序对的意义(即代入顺序对的式子),即$-\sum_{j=x}^{i}[a_{j}\le a_{i+1}]\le -\sum_{j=y}^{i}[a_{j}\le a_{i+1}]$

由于$x>y$,将右式加过来,即$\sum_{j=y}^{x-1}[a_{j}\le a_{i+1}]\le 0$,由于左式非负,因此必然取等号

考虑这个式子是由最初两个式子相加,因此也应取到等号,即$g_{x-1}+calc(x,i)=g_{y-1}+calc(y,i)$,这与$mn_{i}$为最小的$k$矛盾

接下来考虑如何来维护这个$mn_{i}$,直接整体二分,即求出$mn_{mid}$,然后划分为两部分即可

但还有一个问题,考虑如何求$mn_{mid}$,假设询问区间为$[l,r]$,答案(即$mn_{i}$)对应区间为$[x,y]$,此时如果暴力求$[y,mid]$内的顺序对数复杂度显然是不对的,因此考虑优化

类似莫队,维护一个区间$[l',r']$以及该区间内的顺序对数,之后通过移动$l'$和$r'$(需要可持久化线段树维护移动)来得到该区间,接下来每次移动次数为$o((y-x)+(r-l))$,由此即可得总复杂度为$o(nk\log^{2}n)$

首先,每一次开始时,$l'\in [x,y]$且$r'\in [l,r]$(可以归纳),此时相当于要将$r'$移动到$mid$,再将$l'$移动到$y$再移动回$x$,这些年都是$o((y-x)+(r-l))$的

之后考虑将$l'$移动回到$mn_{mid}$,进行搜索左区间,再将$r'$移动到$mid+1$来搜索右区间,最后再把$l'$和$r'$移动回最开始的状态,这样就可以保证复杂度

(由于$|a-b|+|b-c|\ge |a-c|$,这个移动并不需要去实现,而只是证明复杂度)

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 25005
4 #define mid (l+r>>1)
5 int V,n,k,ll,rr,a[N],rt[N],tr[N*20],ls[N*20],rs[N*20];
6 long long sum,g[N],f[N];
7 int New(int k){
8 tr[++V]=tr[k];
9 ls[V]=ls[k];
10 rs[V]=rs[k];
11 return V;
12 }
13 void update(int &k,int l,int r,int x){
14 k=New(k);
15 tr[k]++;
16 if (l==r)return;
17 if (x<=mid)update(ls[k],l,mid,x);
18 else update(rs[k],mid+1,r,x);
19 }
20 int query(int k,int l,int r,int x,int y){
21 if ((!k)||(l>y)||(x>r))return 0;
22 if ((x<=l)&&(r<=y))return tr[k];
23 return query(ls[k],l,mid,x,y)+query(rs[k],mid+1,r,x,y);
24 }
25 int calcl(int x,int y){
26 return query(rt[y],1,n,a[x]+1,n)-query(rt[x],1,n,a[x]+1,n);
27 }
28 int calcr(int x,int y){
29 return query(rt[y-1],1,n,1,a[y]-1)-query(rt[x-1],1,n,1,a[y]-1);
30 }
31 long long calc(int x,int y){
32 while (rr<y)sum+=calcr(ll,++rr);
33 while (x<ll)sum+=calcl(--ll,rr);
34 while (ll<x)sum-=calcl(ll++,rr);
35 while (y<rr)sum-=calcr(ll,rr--);
36 return sum;
37 }
38 void dfs(int l,int r,int x,int y){
39 if (l>r)return;
40 int s=0,k=0;
41 f[mid]=0x3f3f3f3f;
42 for(int i=x;i<=min(mid,y);i++){
43 int s=g[i-1]+calc(i,mid);
44 if (s<f[mid]){
45 f[mid]=s;
46 k=i;
47 }
48 }
49 dfs(l,mid-1,x,k);
50 dfs(mid+1,r,k,y);
51 }
52 int main(){
53 scanf("%d%d",&n,&k);
54 for(int i=1;i<=n;i++)scanf("%d",&a[i]);
55 for(int i=1;i<=n;i++){
56 rt[i]=rt[i-1];
57 update(rt[i],1,n,a[i]);
58 }
59 ll=1,rr=0;
60 for(int i=1;i<=n;i++)f[i]=calc(1,i);
61 for(int i=1;i<k;i++){
62 memcpy(g,f,sizeof(g));
63 dfs(1,n,1,n);
64 }
65 printf("%d",f[n]);
66 }

[luogu5574]任务分配问题的更多相关文章

  1. 分配问题与Hungarian算法

    分配问题与Hungarian算法 分配问题 指派问题 匈牙利算法 匈牙利方法是一种能够在多项式时间内解决分配问题(assignment problem)的组合优化算法.它由Harold Kuhn 与1 ...

  2. 关于const和define的内存分配问题的总结

    关于const和define的内存分配问题 const与#define宏定义的区别----C语言深度剖析 1,  const定义的只读变量在程序运行过程中只有一份拷贝(因为它是全局的只读变量,存放在静 ...

  3. 【Uvalive 2531】 The K-League (最大流-类似公平分配问题)

    [题意] 有n个队伍进行比赛,每场比赛,恰好有一支队伍取胜.一支队伍败.每个队伍需要打的比赛场数相同,给你每个队伍目前已经赢得场数和输得场数,再给你一个矩阵,第 i 行第 j 列 表示队伍 i 和队伍 ...

  4. mmc生产任务分配问题

    mmc生产任务分配问题,本题目简单.

  5. dp资源分配问题

    noip考试中dp中的资源分配问题是一大重点(不定时更新) 以下是一些例题 1.乘积最大 //Gang #include<iostream> #include<cstring> ...

  6. 洛谷P4014 分配问题【最小/大费用流】题解+AC代码

    洛谷P4014 分配问题[最小/大费用流]题解+AC代码 题目描述 有 n 件工作要分配给 n 个人做.第 i 个人做第 j 件工作产生的效益为c ij. 试设计一个将 n 件工作分配给 n 个人做的 ...

  7. [20181229]关于字符串的分配问题.txt

    [20181229]关于字符串的分配问题.txt --//链接:http://www.itpub.net/thread-2107534-1-1.html提到的问题,里面一段英文读起来很绕口:--//百 ...

  8. 记一次ElasticSearch重启之后shard未分配问题的解决

    记一次ElasticSearch重启之后shard未分配问题的解决 环境 ElasticSearch6.3.2,三节点集群 Ubuntu16.04 一个名为user的索引,索引配置为:3 primar ...

  9. Libre 6012 「网络流 24 题」分配问题 (网络流,费用流)

    Libre 6012 「网络流 24 题」分配问题 (网络流,费用流) Description 有n件工作要分配给n个人做.第i个人做第j件工作产生的效益为\(c_{ij}\).试设计一个将n件工作分 ...

随机推荐

  1. hmac和socketserver

    一,hmac 验证客户端的合法性 hmac,检测客户端是否合法,不依赖登录认证 server import os,socket,hmac sk=socket.socket() sk.bind(('12 ...

  2. 洛谷T31018 经典题丶改(LCT+离线)

    真的是一个大好题啊! QWQ首先我们考虑这种问题,如果直接在线做,估计应该是做不了,那我们是不是可以直接考虑离线. 将所有询问都按照\(r\)来排序. 然后依次加入每条边,计算\(a[i]<=n ...

  3. linux性能优化基础——iommu相关配置

    此篇文档介绍了IOMMU相关的信息: https://blog.chaosjohn.com/Check-VT-D-or-IOMMU-under-Linux.html iommu和vt-d都是io半虚拟 ...

  4. 初识HTML02

    HTML 超文本标记语言 什么是超文本标记语言 浏览器能够解释和解析的语言 通过元素的形式构建页面结构和填充内容 构建HTML页面 构建页面的步骤 创建一个扩展名为.html和.html的页面文件 向 ...

  5. Scrum Meeting 0429

    零.说明 日期:2021-4-29 任务:简要汇报两日内已完成任务,计划后两日完成任务 一.进度情况 组员 负责 两日内已完成的任务 后两日计划完成的任务 qsy PM&前端 完成部分后端管理 ...

  6. CSP踩被记

    本来想起个清新脱俗的标题,但碍于语文功底不行,于是光明正大嫖了LiBoyi的高端创意,把这篇博客命名为踩被记. Day -6 用假暴力把真正解拍没了,伤心.Rp有点低 Day -4 信息学考,\(py ...

  7. 2021.10.7 NKOJ周赛总结

    Ⅰ. 自描述序列 问题描述: 序列 1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1,2,2,1,... 看似毫无规律,但若我们将相邻的数字合并 : 1,22,11,2,1,22,1 ...

  8. Spring源码解读(一):Spring的背景起源及框架整体介绍

    一.前言 Spring起源于2002年Rod Johnson写的一本书<Expert One-on-One J2EE>,书里介绍了Java企业应用程序开发情况,并指出Java EE和EJB ...

  9. 高并发场景下JVM调优实践之路

    一.背景 2021年2月,收到反馈,视频APP某核心接口高峰期响应慢,影响用户体验. 通过监控发现,接口响应慢主要是P99耗时高引起的,怀疑与该服务的GC有关,该服务典型的一个实例GC表现如下图: 可 ...

  10. 链表分割 牛客网 程序员面试金典 C++ Python

    链表分割 牛客网 程序员面试金典 C++ Python 题目描述 编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前 给定一个链表的头指针 ListNode* p ...