线段树维护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 开启gzip压缩

    Nginx开启Gzip压缩功能, 可以使网站的css.js .xml.html 文件在传输时进行压缩,提高访问速度,!  Web网站上的图片,视频等其它多媒体文件以及大文件,因为压缩效果不好,所以对于 ...

  2. 导入/导出 数据库/数据库表(wordpress做例子)

    导入数据库: 1. 数据库层面: 没有wordpress的情况下,建立wordpress数据库 create database wordpress; 进入wordpress数据库 use wordpr ...

  3. [CF429E]Points ans Segments_欧拉回路

    Points and Segments 题目链接:www.codeforces.com/contest/429/problem/E 注释:略. 题解: 先离散化. 发现每个位置如果被偶数条线段覆盖的话 ...

  4. storm并行度核心概念介绍剖析

    一.Storm的并行介绍 并行意味着多个任务在不同的节点上,且每个节点都可独立运行,并且相互之间没有依赖. 而在storm上,storm提交的jobs(任务)通过nimbus分发到多个supervis ...

  5. SQL Server 学习之环境搭建

    SQL Server 环境搭建 说明:本文是sqlServer的安装和测试环境的搭建 版本是SQLServer 2005版,由于该版本只能在Windows7或者更低的系统上才能安装,更高的系统请安装S ...

  6. mybatis 的一对一关联查询association

    现在项目的列表查询数据需要查一个总数count, 如果直接写在同一个sql里面,会导致查询速度很慢, 因此,想到使用关联查询,例子如下: 附上代码: 其中遇到的坑哟: 1.association中的s ...

  7. 1.3.4 并发工具类CountDownLatch/Semaphore/CyclicBarrier/FutureTask

    CountDownLatch的2个用途: 1. 所有线程都到达相同的起跑线后,再一起开始跑(并非同时开始,而是队列中一个唤醒另一个)[此情况需到达起跑线后再调用await()等待其他线程] 2. 所有 ...

  8. 20190804-Python基础 第二章 列表和元组

    容器,Python支持一种数据结构的基本概念(容器,基本上就是可包含其他对象的对象.) 两种主要的容器是:序列(如列表和元组)和映射(如字典) Ps: 列表与元组区别,列表可修改,元组不能. 对序列的 ...

  9. .net core 根据数据库生成实体类

    微软最近几年在跨平台上不断发力,很多.net程序员也摩拳擦掌,对微软寄以厚望.就在最近,微软还推出了asp .net core2.0预览版. 通过对.net core的简单尝试,我发现以往我们开发MV ...

  10. 设置centos7中的mysql5.7不区分表名大小写有关操作

    1.#which mysqld          //查看mysql的命令路径 /usr/sbin/mysqld 2.#/usr/sbin/mysqld --verbose --help | grep ...