ZCPC17th E Easy DP Problem

希望更丰富的阅读体验?来我的网站阅读趴!

Problem

由于这题前面的思维推到部分我没有参与,主要是现学(复习)了一下主席树,所以主要讲主席树的部分。

题目可转化为:

给一个长度为 \(n\) 的数组 \(a_i\),有 \(q\) 个询问,每次询问区间 \([l,r]\) 中最大的 \(k\) 个数之和,再加上 \(\sum_{i=1}^{r-l+1}i^2\)。

\(n\le10^5,q\le10^5,a_i\le10^6\)

\(T\le100,\sum n\le5\times10^5,\sum q\le5\times 10^5\)

Solution

主要讲一下这题主席树的写法吧。

以前,我只知道主席树可以用来可持久化,即对于每次修改,都新建一个版本;同时,可以访问之前任意时刻的版本进行查询。

对于一个数组,使用权值线段树找最大的k个数也是很经典的线段树上二分来解决。

求最大的k个数之和,只要多维护一个 \(sum\),在线段树上二分的时候累计答案即可。

而这题需要查询的是区间 \([l,r]\) 上的最大值。

将数组 \(a_i\) 对应到 \(root_i\):

  • \(root_0\) 代表一个全空的权值线段树
  • \(root_1\) 代表只放入了 \(a_1\) 的权值线段树
  • \(root_2\) 放入了 \(a_1,a_2\)
  • ……

那么,想要查询区间 \([1,i]\) 上的最大k个数之和,只需要在线段树 \(root_i\) 上进行上述“线段树上二分”即可。

但是如果要查询区间 \([l,r]\) 上的最大k个数之和呢?类似前缀和与差分,只需要同时查询 \(root_{l-1}\) 和 \(root_r\) 这两颗线段树,节点的值做差即可得到区间 \([l,r]\) 上的节点权值。

Code

#define int ll
#define N 100010
#define M 1000010
int n,q;
struct node
{
int lson, rson, cnt;
ll sum;
#define lson(x) tree[x].lson
#define rson(x) tree[x].rson
#define cnt(x) tree[x].cnt
#define sum(x) tree[x].sum
}tree[N*20];
map<ll, ll>lsh;
ll rlsh[N];
ll lsh_cnt;
int cnt;
ll a[N];
int new_node(int old)
{
cnt++;
tree[cnt] = tree[old];
return cnt;
}
void upd(int p)
{
cnt(p) = cnt(lson(p)) + cnt(rson(p));
sum(p) = sum(lson(p)) + sum(rson(p));
}
void build(int& p, int l, int r)
{
p = new_node(0);
if (l == r)
{
return;
}
int mid = (l + r) >> 1;
build(lson(p), l, mid);
build(rson(p), mid + 1, r);
}
void change(int& p, int p_old, int l, int r,ll v)
{
p = new_node(p_old);
if (l == r)
{
cnt(p)++;
sum(p) += rlsh[v];
return;
}
int mid = (l + r) >> 1;
if (v <= mid)
{
change(lson(p), lson(p_old), l, mid, v);
}
else
{
change(rson(p), rson(p_old), mid + 1, r, v);
}
upd(p);
}
ll ask(int p, int pre, int l, int r,ll k)
{
if (l == r)
{
return k * rlsh[l];
}
ll delta_cnt = cnt(rson(p)) - cnt(rson(pre));
int mid = (l + r) >> 1;
if (k <= delta_cnt)
{
return ask(rson(p), rson(pre), mid + 1, r, k);
}
else
{
return ask(lson(p), lson(pre), l, mid, k - delta_cnt) + sum(rson(p)) - sum(rson(pre));
}
}
int root[N];
ll i2[N];
void solve() {
cin >> n; for (ll i = 1; i <= n; i++) i2[i] = i2[i - 1] + i * i;
lsh.clear();
cnt = 0;
lsh_cnt = 0; for (int i = 1; i <= n; i++)
{
cin >> a[i];
lsh[a[i]] = 0;
}
for (auto it = lsh.begin(); it != lsh.end(); it++)
{
it->second = ++lsh_cnt;
rlsh[lsh_cnt] = it->first;
} build(root[0], 1, lsh_cnt); for (int i = 1; i <= n; i++)
{
change(root[i], root[i - 1], 1, lsh_cnt, lsh[a[i]]);
} cin >> q;
while (q--)
{
int l, r, k;
cin >> l >> r >> k;
ll ans = ask(root[r], root[l - 1], 1, lsh_cnt, k);
ans += i2[r - l + 1];
cout << ans << endl;
} }

ZCPC17th E Easy DP Problem的更多相关文章

  1. HDU 5572 An Easy Physics Problem (计算几何+对称点模板)

    HDU 5572 An Easy Physics Problem (计算几何) 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=5572 Descripti ...

  2. HDU 5572--An Easy Physics Problem(射线和圆的交点)

    An Easy Physics Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/ ...

  3. hdu 5572 An Easy Physics Problem 圆+直线

    An Easy Physics Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/ ...

  4. 2015 ACM-ICPC 亚洲区上海站 A - An Easy Physics Problem (计算几何)

    题目链接:HDU 5572 Problem Description On an infinite smooth table, there's a big round fixed cylinder an ...

  5. @hdu - 6607@ Easy Math Problem

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 求: \[\sum_{i=1}^{n}\sum_{j=1}^{n ...

  6. hdu 6832 A Very Easy Graph Problem 构造树+dfs

    题意: 给你一个n个点m条边的图,对于第i条边,它的长度是2i,对于每一个顶点,它不是0类型,就是1类型.你需要找出来对于所有的"两个不同类型的点之间最短距离"的和 题解(参考:h ...

  7. easy dp

    1.将一堆正整数分为2组,要求2组的和相差最小. //File Name: nod1007.cpp //Author: long //Mail: 736726758@qq.com //Created ...

  8. ACM 2015年上海区域赛A题 HDU 5572An Easy Physics Problem

    题意: 光滑平面,一个刚性小球,一个固定的刚性圆柱体 ,给定圆柱体圆心坐标,半径 ,小球起点坐标,起始运动方向(向量) ,终点坐标 ,问能否到达终点,小球运动中如果碰到圆柱体会反射. 学到了向量模板, ...

  9. 【HDU 5572 An Easy Physics Problem】计算几何基础

    2015上海区域赛现场赛第5题. 题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5572 题意:在平面上,已知圆(O, R),点B.A(均在圆外),向量 ...

  10. BZOJ 3450: Tyvj1952 Easy [DP 概率]

    传送门 题意:$ox?$组成的序列,$?$等概率为$o\ or\ x$,得分为连续的$o$的长度的平方和,求期望得分 一开始没想出来,原因在于不知道如何记录长度 其实我们同时求得分和长度的期望就好了 ...

随机推荐

  1. 『Plotly实战指南』--绘图初体验

    今天,打算通过绘制一个简单的散点图,来开启我们 Plotly 绘图的初次尝试. 本文目的不是介绍如何绘制散点图,而是通过散点图来介绍Plotly 绘图的基础步骤. 1. 绘制散点图:初探 Plotly ...

  2. ffmpeg合并时音画不同步问题及音频软编码实现记录

    最近因为耳机3.5mm接口的一些干扰问题,舍弃了之前的接入方式,需要重新实现网络音频流的接入,在这个过程中遇到了一些问题,特来记录一下~ 一.网络音频流的接入 这个音频流来源各不相同,我这里是udp广 ...

  3. IvorySQL 增量备份与合并增量备份功能解析

    1. 概述 IvorySQL v4 引入了块级增量备份和增量备份合并功能,旨在优化数据库备份与恢复流程.通过 pg_basebackup 工具支持增量备份,显著降低了存储需求和备份时间.同时,pg_c ...

  4. 查看docker容器占用内存

    ps -ef|grep 容器Id 1 2 3 [root@wentao-2 order]# ps -ef|grep 3a61cb3fd4f6 root      7358 12956  0 09:14 ...

  5. 团队小规模本地大模型服务平台搭建 - Windows

    实现目标和考虑因素 部署一个支持多用户同时使用.多模型运行的离线局域网大模型服务器 需要考虑以下几个关键因素: 大模型的加载和管理.使用一个基础大模型,根据需要创建多个专用模型,模型管理方便可靠. 并 ...

  6. Delphi MEMO 循环往上往下滚动

    // 循环往上滚动 if Memo1.Perform(EM_SCROLL,SB_LINEDOWN,0)=0 then begin Memo1.Perform(WM_VSCROLL,SB_TOP,0); ...

  7. delphi Wmi 获取操作系统信息

    uses ActiveX, ComObj; function GetWMIProperty(WMIProperty: string): string; var Wmi, Objs, Obj: OleV ...

  8. TCP延迟调优之PSH参数与passt延迟问题修复

    qemu中使用passt来作为虚拟机的网卡NAT实现,希望能够利用它IP地址与host一致的优点.这本来是没有啥问题的,但是不知道为什么它的TCP入口流量的延迟很严重. 好吧,反正以后总是要改pass ...

  9. vue-element-admin整合服务端代理api

    1. 找到vue.config.js,在devServer中编辑如下 devServer: { port: port, open: true, overlay: { warnings: false, ...

  10. WPF静态资源StaticResource和动态资源DynamicResource有什么区别,x:Static又是什么意思?

    什么叫WPF的资源(Resource) 资源是保存在可执行文件中的一种不可执行数据.WPF中资源用ResourceDictionary类表示,这个类就是一个字典,字典的key和value都是objec ...