预处理出每个原子最近的不能合并的位置

枚举当前位置和前面断开的位置合并

发现还是不能过

考虑用选段树优化

但是因为每次转移的最优点是在前面可以合并的范围内 dp值加上当前的到该点的最大值

因为每个位置的最大值每次更新不是只更新一个位置

是一次更新一段位置

所以直接维护复杂度爆炸

有种方法(套路) 是把最值的更新改为值的加减

因为每次是更新一段区间

且每个点到当前的位置的最值是单调不减的

所以每次的修改就可以是一段一段的

可以用单调栈来维护每种值的区间

就可以进行区间修改

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define C getchar()-48
inline ll read()
{
ll s=0,r=1;
char c=C;
for(;c<0||c>9;c=C) if(c==-3) r=-1;
for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
return s*r;
}
const int N=1e5+10,inf=1e9;
int n,qm;
int p[N],v[N],q[N];
int vis[N];
int dp[N];
int dv[N],dr[N],top;
struct xin{
int del,mn;
}tr[N<<2];
inline void up(int x)
{
tr[x].mn=min(tr[x<<1].mn,tr[x<<1|1].mn)+tr[x].del;
}
inline void down(int x)
{
tr[x<<1].del=tr[x<<1|1].del=tr[x].del;
tr[x].del=0;
}
inline void add(int x,int l,int r,int ql,int qr, int v)
{
if(ql<=l&&r<=qr){tr[x].del+=v,tr[x].mn+=v;return;}
int mid=(l+r)>>1;
if(ql<=mid) add(x<<1,l,mid,ql,qr,v);
if(mid<qr) add(x<<1|1,mid+1,r,ql,qr,v);
up(x);
}
inline int ask(int x,int l,int r,int ql,int qr)
{
if(ql<=l&&r<=qr){return tr[x].mn;}
int mid=(l+r)>>1,mn=inf;
if(ql<=mid) mn=min(mn,ask(x<<1,l,mid,ql,qr));
if(mid<qr) mn=min(mn,ask(x<<1|1,mid+1,r,ql,qr));
up(x);
return mn+tr[x].del;
}
int main()
{
freopen("array.in","r",stdin);
freopen("array.out","w",stdout);
n=read();qm=n;vis[0]=1;dv[0]=inf;dr[0]=0;
for(int i=1;i<=n;i++) p[i]=read(),v[i]=read();
for(int i=n;i>=1;i--)
{
while(!vis[p[qm]]){vis[p[qm]]=1;qm--;}
q[i]=qm;
vis[p[i]]=0;
}
for(int i=1;i<=n;i++)
{
add(1,1,n,i,i,v[i]);
while(dv[top]<v[i])
{
add(1,1,n,dr[top-1]+1,dr[top],v[i]-dv[top]);
top--;
}
dv[++top]=v[i],dr[top]=i;
dp[i]=ask(1,1,n,q[i]+1,i);
add(1,1,n,i+1,i+1,dp[i]);
}
cout<<dp[n];
return 0;
}

还有位大佬用multiset维护

#include<bits/stdc++.h>
using namespace std; #define Abigail inline void
typedef long long LL; const int N=100000,INF=(1<<30)-1; multiset<int>t;
int n,a[N+9],b[N+9],data[N+9],last[N+9],l[N+9];
int sum[N+9],wei[N+9],f[N+9],hd,tl; Abigail into(){
scanf("%d",&n);
for (int i=1;i<=n;++i)
scanf("%d%d",&a[i],&b[i]);
} Abigail work(){
for (int i=1;i<=n;++i)
l[i]=max(l[i-1],last[a[i]]+1),last[a[i]]=i;
//预处理每一个位置为结尾可以取的转移的区间左端点
hd=1;
int k;
for (int i=1;i<=n;++i){
k=i-1;
for (;hd<tl&&wei[hd+1]<l[i];++hd)
t.erase(t.find(sum[hd]));
//把不在转移区间的位置去掉
for (;hd<=tl&&b[i]>data[tl];--tl)
t.erase(t.find(sum[tl])),k=wei[tl];
//更新阶梯型(max{b[j]..b[i]})
data[++tl]=b[i];
wei[tl]=k;
//加入第i个位置
if (hd^tl){
sum[tl]=f[wei[tl]]+data[tl];
//把位置i所在的阶梯中最优的值sum[tl]计算出来
t.insert(sum[tl]);
//加入set中
t.erase(t.find(sum[hd]));
//开头的那一段阶梯中会有一部分不可取,一部分可取
}
sum[hd]=f[l[i]-1]+data[hd];
//采取开头最优的那段
t.insert(sum[hd]);
//加入set中
f[i]=*t.begin();
}
} Abigail outo(){
printf("%d\n",f[n]);
} int main(){
freopen("array.in","r",stdin);
freopen("array.out","w",stdout);
into();
work();
outo();
return 0;
}

【简】题解 AWSL090429 【原子】的更多相关文章

  1. 【简】题解 AWSL090429 【市场】

    因为这有个时间的限制 并且  求的时间都是前缀和 那么 我们可以根据时间将排序 因为题中没有修改可以直接用背包预处理出答案 但是因为题目ci mi<=1e9   vi<=300 所以发现不 ...

  2. 【简】题解 AWSL090429 【噪音】

    因为每次加上一头奶牛 是什么不重要 牛棚之间贡献除清空操作外无影响 就只要考虑 每个牛棚清空分x次 的贡献 x之和为k       求贡献和最小 一个牛棚清空x次 显然平均清空贡献最小 再用等差数列的 ...

  3. 【简】题解 AWSL090429 【数塔问题】

    因为每次只ban一个点 而且不是永久性的 预处理出每个点从上往下和从下往上的最大值 每次询问直接暴力 被ban掉点那行去掉那点的最大值 也可以直接预处理出每行的最大值和次大值 还有种做法貌似可以过 预 ...

  4. 【简】题解 AWSL090429 【聚会】

    这题直接换根dp 记录在要转移的点的子树中有多少牛 #include<bits/stdc++.h> using namespace std; #define ll long long #d ...

  5. 【简】题解 AWSL090429 【价值】

    先考虑当要选的物品一定时 显然有个贪心 wi越小的要越先选 所以先按wi从小到大拍序 因为发现正着递推要记录的状态很多 并且wi的贡献与后面选了几个物品有关 考虑正难则反 倒着递推 提前计算wi的贡献 ...

  6. DP笔记

    这是一篇蒟蒻被大佬踩爆后写的笔记 套路 0.贪心(废话)(排序...) 1.dp预处理出要用的东西 2.两头同时dp 3.化简题目中本质相同的东西 转化模型 4.数学计算优化 5.分析题目数据考虑该从 ...

  7. 【简】题解 P5283 [十二省联考2019]异或粽子

    传送门:P5283 [十二省联考2019]异或粽子 题目大意: 给一个长度为n的数列,找到异或和为前k大的区间,并求出这些区间的异或和的代数和. QWQ: 考试时想到了前缀异或 想到了对每个数按二进制 ...

  8. 【简】题解 P4297 [NOI2006]网络收费

    传送门:P4297 [NOI2006]网络收费 题目大意: 给定一棵满二叉树,每个叶节点有一个状态(0,1),任选两个叶节点,如果这两个叶节点状态相同但他们的LCA所管辖的子树中的与他们状态相同的叶节 ...

  9. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

随机推荐

  1. mac下将python2.7改为python3

    mac下将python2.7改为python3 查看当前电脑python版本 python -V 修改.bash_profile文件 vi ~/.bash_profile //编辑bash_profi ...

  2. JSON实现序列化dump和dumps方法,JSON实现反序列化loads和load方法

    通过文件操作,我们可以将字符串写入到一个本地文件.但是,如果是一个对象(例如列表.字典.元组等),就无 法直接写入到一个文件里,需要对这个对象进行序列化,然后才能写入到文件里. 设计一套协议,按照某种 ...

  3. ndarray 数组的创建和变换

    ndarray数组的创建方法 1.从python中的列表,元组等类型创建ndarray数组 x = np.array(list/tuple) x = np.array(list/tuple,dtype ...

  4. kafka数据清理

    Kafka将数据持久化到了硬盘上,允许你配置一定的策略对数据清理,清理的策略有两个,删除和压缩. 数据清理的方式 删除 log.cleanup.policy=delete启用删除策略直接删除,删除后的 ...

  5. [luogu7831]Travelling Merchant

    考虑不断找到以下两种类型的边,并维护答案: 1.终点出度为0的边,那么此时即令$ans_{x}=\min(ans_{x},\max(r,ans_{y}-p))$​ 2.(在没有"终点出度为0 ...

  6. [gym103055H]Grammy and HearthStone

    题目即要求构造一个长为$2n$的序列$a_{i}$,满足$\forall 1\le i\le n$,$i$恰好出现两次,假设分别是$a_{x}=a_{y}=i(x<y)$,即要求$y-x=i$ ...

  7. Hi3516开发笔记(三):Hi3516虚拟机基础环境搭建之交叉编译环境境搭建以及开机启动脚本分析

    前言   前面进行了可以传输,那么写一个简单的C程序来交叉编译并传入运行.   虚拟机   上一篇搭建的虚拟机环境,包含了sftp传递文件,网络能ping通,基于上一篇的虚拟机继续搭建.   海思交叉 ...

  8. ASP .Net Core 在 CentOS8 ARM 下连接 SQL Server 2008 R2(Hypervisor)

    本文主要记录在 ARM 系统下无法连接SQL Server 2008 R2 的解决过程. 解决方案是使用 ODBC 的方式连接数据库,进行操作. 手上有公司的华为鲲鹏云计算 ARM 架构的 CentO ...

  9. 【贾志豪NOIP模拟题】慰问员工 cheer 【最小生成树】【对边权值的一些处理】

    Description LongDD 变得非常懒, 他不想再继续维护供员工之间供通行的道路. 道路被用来连接 N(5 <= N <= 10,000)个房子, 房子被连续地编号为 1..N. ...

  10. 【状压dp】Hamiton路径

    描述 给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Hamilton路径的定义是从 0 到 n-1 不重不漏地经过每个点 ...