线段树维护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. Python基础总结之初步认识---class类(中)。第十四天开始(新手可相互督促)

    昨天简单的认识类怎么定义,什么是类,类如何调用.今天的笔记会大概补充一些内容,明天的笔记会细致讲解,加深个印象即可 今天我们在了解下:类的属性,类属性属于类也属于实例化对象.也就是说类的实例化对象可以 ...

  2. 【Jmeter源码解读】002——程序入口类NewDriver.java

    1.运行环境的检查 2.刚才初始化的 classloader 加载类 org.apache.jmeter.JMeter 然后通过 java 反射的方式来调用 org.apache.jmeter.JMe ...

  3. InnoDB 中的锁实现

    InnoDB 中的锁实现 原贴:InnoDB 锁系统及死锁检测实现分析 InnoDB 中,所有事务加的行锁通过一个全局的 hash 表 lock_sys 维护: /* The lock system ...

  4. 盒模型中padding、border、margin的区别

    在CSS中,规定了一种基本设计模型——盒模型(也叫框模型),如图所示: 其中包含了四部分内容:element/元素(即图中文字).padding/内边框(图中两个红色边框之间白色部分).border/ ...

  5. 如何使用RedisTemplate访问Redis数据结构之字符串操作

    Redis 数据结构简介 Redis 可以存储键与5种不同数据结构类型之间的映射,这5种数据结构类型分别为String(字符串).List(列表).Set(集合).Hash(散列)和 Zset(有序集 ...

  6. nginx运行基本指令

    测试配置文件: 安装路径下的/nginx/sbin/nginx -t启动: 安装路径下的/nginx/sbin/nginx停止 安装路径下的/nginx/sbin/nginx -s stop 或者是: ...

  7. android 一个SQLite数据库多个数据表的基本使用框架 (带demo)

    android 一个SQLite数据库多个数据表(带demo) 前言        demo演示        一.搭建        二.建立实体类        三.建立数据库操作类        ...

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

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

  9. sql server 数据库中明明有值但是查询怎么都查不到值

    产生原因是因为编码问题 数据库是英文版  但是数据库中数据又是中文的 所以查询中文时需要加上N select * from customer where Username=N'张三'

  10. iPhone开发视频教程 Objective-C部分

    第一.二章  OC基础语法 iPhone开发教程 第一章 OC基础语法  iPhone开发概述-必看 (1.1) http://www.apkbus.com/android-102215-1-1.ht ...