线段树维护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. 使用Navicat为数据库表建立触发器

    打开Navicat   打开数据表所在的数据库,右击需要新增字段的数据库表,然后点击[设计表]   此时进入表设计界面   点击[触发器]标签页,输入触发器名称,如trigger1   选择触发条件, ...

  2. TemplateView , ListView ,DetailView三种常用类视图用法

    参考博客: https://blog.csdn.net/weixin_36571185/article/details/74280102

  3. new pdo 连接很慢的原因和解决办法

    1.使用IP而不是域名,使用域名会让PDO在连接之前进行一次不必要的dns lookup,当DNS缓存过于巨大的时候,这个问题可能会更严重.(即使是运行在本机,使用 127.0.0.1 而不是 loc ...

  4. DP的初级问题——01包、最长公共子序列、完全背包、01包value、多重部分和、最长上升子序列、划分数问题、多重集组合数

    当初学者最开始学习 dp 的时候往往接触的是一大堆的 背包 dp 问题, 那么我们在这里就不妨讨论一下常见的几种背包的 dp 问题: 初级的时候背包 dp 就完全相当于BFS DFS 进行搜索之后的记 ...

  5. LC 94. Binary Tree Inorder Traversal

    问题描述 Given a binary tree, return the inorder traversal of its nodes' values. (左 - 根 - 右) Example: In ...

  6. 爬虫-selenium 模块-02

    目录 selenium 模块 chromedriver 浏览器驱动下载与存放 PhantomJS 无界面浏览器 标签元素查找方法 xpath 格式用法 获取标签属性 等待元素被加载 元素交互操作 点击 ...

  7. POJ 2485 Prim 找最长的边

    A国没有高速公路,因此A国的交通很困难.政府意识到了这个问题并且计划建造一些高速公路,以至于可以在不离开高速公路的情况下在任意两座城镇之间行驶. A国的城镇编号为1到N, 每条高速公路连接这两个城镇, ...

  8. springsecurity学习

    首先讲一下,没有用到数据库,然后觉得重要的就是security的配置securityConfig.class,不太会说(好像也不太会用),上图吧,也是学习狂神过来的 项目结构 大致效果 pom.xml ...

  9. sipp命令 各参数含义

    sipp -sn uac 172.31.89.4:5060 -r 1 -rp 3000 -inf data.csv -p 7098 -i 172.31.89.242 -s 8001 -sf uac_o ...

  10. Node.js Express项目搭建

    讲干货,不啰嗦,Express 是一个简洁而灵活的 node.js Web应用框架,使用 Express 可以快速地搭建一个完整功能的网站.本教程介绍如何从零开始搭建Express项目. 开发环境:w ...