[CSP-S模拟测试]:F(DP+线段树)
题目传送门(内部题49)
输入格式
第一行四个整数$n,q,a,b$。
接下来$n$行每行一个整数$p_i$。
输出格式
一行一个整数表示答案。
样例
样例输入:
10 3 3 7
样例输出:
数据范围与提示
对于$30\%$的数据:$n,q\leqslant 2,000$
对于所有数据:
$1\leqslant n,q\leqslant {10}^5$
$1\leqslant p_i\leqslant n$
题解
首先,我们考虑$30\%$的算法怎么办?
考虑$DP$,定义$dp[i][j]$表示到了第$i$步,一个指针在$p_i$,另一个指针在$j$的最短步数。
那么我们可以里出状态转移方程:
$\alpha.dp[i][j]=dp[i-1][j]+|p_i-p_{i-1}|$(上一次和这一次移动的是一个指针)
$\beta.dp[i][p_{i-1}]=dp[i-1][j]+|p_i-j|$(上一次和这一次移动的不是一个指针)
那么我们接着考虑如何优化。
发现转移$\alpha$其实就是将整个区间都加了$|p_i-p_{i-1}|$,而转移$\beta$我们可以维护$dp[i][j]+j$和$dp[i][j]-j$的最小值即可。
所以考虑线段树优化,即可得到满分。
时间复杂度:$\Theta(n\log n)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h>
#define L(x) x<<1
#define R(x) x<<1|1
using namespace std;
int n,q,a,b;
int p[100001];
long long tr[4][400001];
void pushup(int x)
{
tr[0][x]=min(tr[0][L(x)],tr[0][R(x)]);
tr[1][x]=min(tr[1][L(x)],tr[1][R(x)]);
tr[2][x]=min(tr[2][L(x)],tr[2][R(x)]);
}
void pushdown(int x)
{
if(!tr[3][x])return;
tr[0][L(x)]+=tr[3][x];
tr[0][R(x)]+=tr[3][x];
tr[1][L(x)]+=tr[3][x];
tr[1][R(x)]+=tr[3][x];
tr[2][L(x)]+=tr[3][x];
tr[2][R(x)]+=tr[3][x];
tr[3][L(x)]+=tr[3][x];
tr[3][R(x)]+=tr[3][x];
tr[3][x]=0;
}
void build(int x,int l,int r)
{
if(l==r)
{
if(l==b)
{
tr[0][x]=0;
tr[1][x]=l;
tr[2][x]=-l;
}
return;
}
int mid=(l+r)>>1;
build(L(x),l,mid);
build(R(x),mid+1,r);
pushup(x);
}
void change(int x,int l,int r,int w,long long k)
{
if(l==r)
{
tr[0][x]=min(tr[0][x],k);
tr[1][x]=tr[0][x]+l;
tr[2][x]=tr[0][x]-l;
return;
}
int mid=(l+r)>>1;
pushdown(x);
if(w<=mid)change(L(x),l,mid,w,k);
else change(R(x),mid+1,r,w,k);
pushup(x);
}
long long ask1(int x,int l,int r,int L,int R)
{
if(R<l||r<L)return 200209230020020923;
if(L<=l&&r<=R)return tr[2][x];
int mid=(l+r)>>1;
pushdown(x);
return min(ask1(L(x),l,mid,L,R),ask1(R(x),mid+1,r,L,R));
}
long long ask2(int x,int l,int r,int L,int R)
{
if(R<l||r<L)return 200209230020020923;
if(L<=l&&r<=R)return tr[1][x];
int mid=(l+r)>>1;
pushdown(x);
return min(ask2(L(x),l,mid,L,R),ask2(R(x),mid+1,r,L,R));
}
int main()
{
scanf("%d%d%d%d",&n,&q,&a,&b);
memset(tr[0],0x3f,sizeof(tr[0]));
memset(tr[1],0x3f,sizeof(tr[1]));
memset(tr[2],0x3f,sizeof(tr[2]));
build(1,1,n);
for(int i=1;i<=q;i++)
{
scanf("%d",&b);
tr[0][0]=min(ask1(1,1,n,1,b)+b,ask2(1,1,n,b,n)-b);
tr[0][1]+=abs(a-b);
tr[1][1]+=abs(a-b);
tr[2][1]+=abs(a-b);
tr[3][1]+=abs(a-b);
change(1,1,n,a,tr[0][0]);
a=b;
}
cout<<tr[0][1]<<endl;
return 0;
}
rp++
[CSP-S模拟测试]:F(DP+线段树)的更多相关文章
- [CSP-S模拟测试]:bird(线段树优化DP)
题目传送门(内部题89) 输入格式 第一行两个数$n$和$k$,分别表示小鸟的只数和$R$装弹时间.接下来$n$行,每行两个数$l,r$表示$n$只小鸟初始时的头和尾的$x$坐标. 输出格式 输出一个 ...
- [CSP-S模拟测试]:Weed(线段树)
题目描述 $duyege$的电脑上面已经长草了,经过辨认上面有金坷垃的痕迹.为了查出真相,$duyege$准备修好电脑之后再进行一次金坷垃的模拟实验.电脑上面有若干层金坷垃,每次只能在上面撒上一层高度 ...
- [CSP-S模拟测试]:光线追踪(线段树)
题目背景 初中时的乔猫试着组建了$NEWorld$开发组,可是不久之后却因为合作上的问题(和乔猫工程水平差,代码混乱的问题),开发组成员之间常常产生矛盾,关系越来越不如以前......一年下来,受到长 ...
- [CSP-S模拟测试]:椎(线段树维护区间最值和单调栈)
题目描述 虽不能至,心向往之. $Treap=Tree+Heap$ 椎$=$树$+$堆 小$\pi$学习了计算机科学中的数据结构$Treap$. 小$\pi$知道$Treap$指的是一种树. 小$\p ...
- [CSP-S模拟测试]:string(线段树)
题目描述 给定一个由小写字母组成的字符串$s$. 有$m$次操作,每次操作给定$3$个参数$l,r,x$. 如果$x=1$,将$s[l]~s[r]$升序排序: 如果$x=0$,将$s[l]~s[r]$ ...
- [CSP-S模拟测试]:Permutation(线段树+拓扑排序+贪心)
题目描述 你有一个长度为$n$的排列$P$与一个正整数$K$你可以进行如下操作若干次使得排列的字典序尽量小对于两个满足$|i−j|\geqslant K$且$|P_i−P_j|=1$的下标$i$与$j ...
- [CSP-S模拟测试]:f(Trie树+二分答案+meet in middle+two pointers)
题目传送门(内部题67) 输入格式 第一行,三个整数$n$.$k$.$p$.第二行,$n$个自然数,表示$\{a_i\}$. 输出格式 输出一行,两个自然数,表示$f(res)$.$res$. 样例 ...
- ZOJ 3349 Special Subsequence 简单DP + 线段树
同 HDU 2836 只不过改成了求最长子串. DP+线段树单点修改+区间查最值. #include <cstdio> #include <cstring> #include ...
- hdu 3016 dp+线段树
Man Down Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- cf834D(dp+线段树区间最值,区间更新)
题目链接: http://codeforces.com/contest/834/problem/D 题意: 每个数字代表一种颜色, 一个区间的美丽度为其中颜色的种数, 给出一个有 n 个元素的数组, ...
随机推荐
- paper 164: Siamese网络--相似度量方法
简介: Siamese网络是一种相似性度量方法,当类别数多,但每个类别的样本数量少的情况下可用于类别的识别.分类等.传统的用于区分的分类方法是需要确切的知道每个样本属于哪个类,需要针对每个样本有 ...
- python3下tomorow模块报语法错误def async(n, base_type, timeout=None): ^ SyntaxError: invalid syntax
python3 pip 安装tomorrow模块,调用时候会报错:def async(n, base_type, timeout=None): ^ SyntaxError: invalid synta ...
- 同源策略和跨域资源共享(CROS)
同源策略 Same-origin policy - Web security | MDN 跨站资源共享 Cross-Origin Resource Sharing (CORS) - HTTP | MD ...
- 测开之路五十六:实现类似unittest的断言
import inspect class Case(object): """ 实现断言 """ def __init__(self): se ...
- PAT甲级【2019年9月考题】——A1160 Forever【20】
7-1 Forever (20 分) "Forever number" is a positive integer A with K digits, satisfying the ...
- ctDNA的分析理论上也可以为多样性的肿瘤
导语 肺腺癌(LUAD)和肺鳞癌(LUSC)是最常见的非小细胞肺癌类型.循环肿瘤DNA(ctDNA)是由凋亡或坏死的肿瘤细胞释放并在血液中循环的小片段DNA.与常规肿瘤活检相比,ctDNA检测具有一定 ...
- luoguP3128 [USACO15DEC]最大流Max Flow 题解(树上差分)
链接一下题目:luoguP3128 [USACO15DEC]最大流Max Flow(树上差分板子题) 如果没有学过树上差分,抠这里(其实很简单的,真的):树上差分总结 学了树上差分,这道题就极其显然了 ...
- poj1426 Find The Multiple (DFS)
题目: Find The Multiple Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 41845 Accepted: ...
- WPF-将DataGrid控件中的数据导出到Excel
原文:WPF-将DataGrid控件中的数据导出到Excel 导出至Excel是非常常见,我们可以用很多类库,例如Aspose.NOPI.Interop,在这里我们使用微软自家的工具.我的WPF绑定的 ...
- 【目录】sql server 进阶篇系列
随笔分类 - sql server 进阶篇系列 sql server 下载安装标记 摘要: SQL Server 2017 的各版本和支持的功能 https://docs.microsoft.com/ ...