线段树维护dp

题目大意

给定初始大小为 $N$ 的正整数集合。定义两个数$x$和$y$建立联系的的代价为 $|x-y|$。我们定义整数集合的代价为:将每个整数都与至少一个另外的整数建立联系之后,所有联系的最小代价之和。如果集合大小小于等于1,则代价为 0。

要求动态维护这个正整数集合的代价。

$n \le 200000$


题目分析

常规的线段树维护dp

考虑在权值上处理这个问题:对于一个区间$[l,r]$,在$(l,r)$中的数肯定是自身配对了才优。也就是说一个区间可以被概括成四个状态:$00,01,10,11$其中$0$表示这一个端点暂时没有配对,$1$表示这个端点已经内部配对了。

接下去就是常规的权值线段树处理dp

 #include<bits/stdc++.h>
typedef long long ll;
const ll INF = 1ll<<;
const int maxn = ;
const int LIM = ;
const int maxNode = ; struct node
{
int mn,mx,ls,rs,val;
ll f00,f01,f10,f11;
}f[maxNode];
int n,m,rt,tot,a[maxn];
int stk[maxn<<],top; int read()
{
char ch = getchar();
int num = , fl = ;
for (; !isdigit(ch); ch=getchar())
if (ch=='-') fl = -;
for (; isdigit(ch); ch=getchar())
num = (num<<)+(num<<)+ch-;
return num*fl;
}
void pushup(int rt)
{
int l = f[rt].ls, r = f[rt].rs, gap = f[r].mn-f[l].mx;
if (!l&&!r){
f[rt].f00 = f[rt].f01 = f[rt].f10 = f[rt].f11 = INF;
}else if (!l||!r){
f[rt].mn = f[l+r].mn, f[rt].mx = f[l+r].mx;
f[rt].f00 = f[l+r].f00, f[rt].f01 = f[l+r].f01;
f[rt].f10 = f[l+r].f10, f[rt].f11 = f[l+r].f11;
}else{
f[rt].mn = f[l].mn, f[rt].mx = f[r].mx;
f[rt].f00 = std::min(std::min(f[l].f00+f[r].f00+gap, f[l].f00+f[r].f10+gap), std::min(f[l].f01+f[r].f00+gap, f[l].f01+f[r].f10));
f[rt].f01 = std::min(std::min(f[l].f00+f[r].f01+gap, f[l].f00+f[r].f11+gap), std::min(f[l].f01+f[r].f01+gap, f[l].f01+f[r].f11));
f[rt].f10 = std::min(std::min(f[l].f10+f[r].f00+gap, f[l].f10+f[r].f10+gap), std::min(f[l].f11+f[r].f00+gap, f[l].f11+f[r].f10));
f[rt].f11 = std::min(std::min(f[l].f10+f[r].f01+gap, f[l].f10+f[r].f11+gap), std::min(f[l].f11+f[r].f01+gap, f[l].f11+f[r].f11));
}
}
void insert(int &rt, int l, int r, int c, int w)
{
if (!rt){
if (top) rt = stk[top--];
else rt = ++tot;
f[rt].ls = f[rt].rs = f[rt].val = f[rt].f00 = f[rt].f01 = f[rt].f10 = f[rt].f11 = ;
}
f[rt].val += w;
if (l==r) f[rt].mn = f[rt].mx = c, f[rt].f11 = INF;
else{
int mid = (l+r)>>;
if (c <= mid)
insert(f[rt].ls, l, mid, c, w);
else insert(f[rt].rs, mid+, r, c, w);
pushup(rt);
}
if (!f[rt].val) stk[++top] = rt, rt = ;
}
int main()
{
n = read(), m = read();
for (int i=; i<=n; i++) insert(rt, , LIM, read(), );
for (int i=; i<=m; i++)
{
int opt = read()==?:-;
insert(rt, , LIM, read(), opt);
printf("%lld\n",f[].f11);
}
return ;
}

END

【线段树 dp】8.6集合的更多相关文章

  1. Tsinsen A1219. 采矿(陈许旻) (树链剖分,线段树 + DP)

    [题目链接] http://www.tsinsen.com/A1219 [题意] 给定一棵树,a[u][i]代表u结点分配i人的收益,可以随时改变a[u],查询(u,v)代表在u子树的所有节点,在u- ...

  2. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

  3. 模板—字符串—后缀自动机(后缀自动机+线段树合并求right集合)

    模板—字符串—后缀自动机(后缀自动机+线段树合并求right集合) Code: #include <bits/stdc++.h> using namespace std; #define ...

  4. 【Foreign】阅读 [线段树][DP]

    阅读 Time Limit: 10 Sec  Memory Limit: 256 MB Description Input Output Sample Input 0 10 4 10 2 3 10 8 ...

  5. Points Division(线段树+DP)2019牛客暑期多校训练营(第一场)

    题意:https://ac.nowcoder.com/acm/contest/881/I 给你n个平面上的点,每个点有a.b两个权值,现在让你划分成两个区域(要求所有A集合里的点不能在任何B集合里的点 ...

  6. 洛谷 P5280 - [ZJOI2019]线段树(线段树+dp,神仙题)

    题面传送门 神仙 ZJOI,不会做啊不会做/kk Sooke:"这八成是考场上最可做的题",由此可见 ZJOI 之毒瘤. 首先有一个非常显然的转化,就是题目中的"将线段树 ...

  7. lightoj1085 线段树+dp

    //Accepted 7552 KB 844 ms //dp[i]=sum(dp[j])+1 j<i && a[j]<a[i] //可以用线段树求所用小于a[i]的dp[j ...

  8. [CF 474E] Pillars (线段树+dp)

    题目链接:http://codeforces.com/contest/474/problem/F 意思是给你两个数n和d,下面给你n座山的高度. 一个人任意选择一座山作为起始点,向右跳,但是只能跳到高 ...

  9. HDU-3872 Dragon Ball 线段树+DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3872 题意:有n个龙珠按顺序放在一列,每个龙珠有一个type和一个权值,要求你把这n个龙珠分成k个段, ...

随机推荐

  1. nginx源码安装(CentOS版)

    准备工作: 1) 配好网易yum源 登录此网站(http://mirrors.163.com/.help/centos.html),下载相应版本的yum源至服务器的/etc/yum.repos.d/目 ...

  2. [转帖]Windows安全认证是如何进行的?[Kerberos篇]

    Windows安全认证是如何进行的?[Kerberos篇] NTLM 的简单看了一下 基本上了解了.. 这个KERBEROS 的看不太懂 感觉说的我也有点迷糊.. 虽然是对称加密的 但是不清不楚的.. ...

  3. 添加 godoc 模块

    获取godoc源码go get -d golang.org/x/tools/cmd/godoc 或 go get golang.org/x/tools/cmd/godoc 如果 下不到源码,就用43服 ...

  4. Python解Leetcode: 724. Find Pivot Index

    leetcode 724. Find Pivot Index 题目描述:在数组中找到一个值,使得该值两边所有值的和相等.如果值存在,返回该值的索引,否则返回-1 思路:遍历两遍数组,第一遍求出数组的和 ...

  5. (二十二)自定义简化版JDBC(Dbutils框架的设计思想)

    目录 元数据概念 DataBaseMetaData ParameterMetaData ResultSetMetaData 编写简化版的JDBC O-R Mapping 概念 自定义简化版JDBC 元 ...

  6. 牛客 133D 挑选队友 (分治FFT)

    大意: $n$个人, 分别属于$m$个组, 要求选出$k$个人, 使得每组至少有一人, 求方案数. 显然答案为$\prod((1+x)^{a_i}-1)$的第$k$项系数, 分治$FFT$即可. #i ...

  7. js文字跑马灯

    实现文字跑马灯效果,主要控制scrollLeft. 效果图如下 代码如下 <html> <head> <script type="text/javascript ...

  8. docker 入门5 - 栈 【翻译】

    入门,第 5 部分:堆栈 先决条件 安装 Docker 版本 1.13 或更高版本. 获取第 3 部分先决条件中所述的 Docker Compose. 获取 Docker Machine,如第 4 部 ...

  9. C#/.net中出现 "GDI+中发生一般性错误"解决方案

    有时我们在读取本地图片,调用 Image.Save() 方法,将其另保存为其他格式时,经常会碰到一个错误:“GDI+中发生一般性错误”:一般出现这种错误有 3 种可能: 1.保存路径不存在或者错误: ...

  10. 解决设置了display:none的元素,会先展示再隐藏

    问题:元素明明设置了display:none,但是在刷新页面的时候却会先显示了出来,然后才会隐藏,实现display:none 原因:由于元素渲染的时候,样式还没有应用上去,导致的 解决办法:使用内联 ...