题目链接:点击查看

题目大意:给出一个长度为 n 的数列 a 和数列 b,然后需要维护一个前缀和 c,c 的定义如下:c[ i ] = max( c[ i - 1 ] + b[ i ] , a[ i ] )

现在需要执行 m 次操作,每次操作分为下列三种类型:

  1. 1 x y:令 a[ x ] = y
  2. 2 x y:令 b[ x ] = y
  3. 3 x:输出 c[ x ]

题目分析:自己手玩一下不难发现,c[ x ] 的取值范围无非就是下列的情况中取最大值:

  1. b[ 1 ] + b[ 2 ] + ... + b[ x ]
  2. a[ 1 ] + b[ 2 ] + ... + b[ x ]
  3. a[ 2 ] + b[ 3 ] + ... + b[ x ]
  4. ......
  5. a[ i - 1 ] + b[ x ]
  6. a[ x ]

对于数组 b 维护一个前缀和 sum[ x ] = b[ 1 ] + b[ 2 ] + ... + b[ x ]

那么上述公式化简为:

然后分别用树状数组和线段树维护一下数组 b 的前缀和 sum 和 ( a[ i ] - sum[ i ] ) 的最大值即可

当然统一用线段树维护也没问题,但单独维护的话可能更好实现一些

代码:

//#pragma GCC optimize(2)
//#pragma GCC optimize("Ofast","inline","-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=1e6+100;int n,m;LL a[N],b[N],c[N];int lowbit(int x)
{return x&(-x);
}void add(int x,LL val)
{for(int i=x;i<=n;i+=lowbit(i))c[i]+=val;
}LL ask(int x)
{LL ans=0;for(int i=x;i>0;i-=lowbit(i))ans+=c[i];return ans;
}struct Node
{int l,r;LL mmax,lazy;
}tree[N<<2];void pushup(int k)
{tree[k].mmax=max(tree[k<<1].mmax,tree[k<<1|1].mmax);
}void pushdown(int k)
{if(tree[k].lazy){LL lz=tree[k].lazy;tree[k].lazy=0;tree[k<<1].mmax+=lz;tree[k<<1|1].mmax+=lz;tree[k<<1].lazy+=lz;tree[k<<1|1].lazy+=lz;}
}void build(int k,int l,int r)
{tree[k].l=l;tree[k].r=r;tree[k].lazy=0;if(l==r){tree[k].mmax=a[l]-ask(l);return;}int mid=l+r>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);pushup(k);
}void update(int k,int l,int r,LL val)
{if(tree[k].l>r||tree[k].r<l)return;if(tree[k].l>=l&&tree[k].r<=r){tree[k].mmax+=val;tree[k].lazy+=val;return;}pushdown(k);update(k<<1,l,r,val);update(k<<1|1,l,r,val);pushup(k);
}LL query(int k,int l,int r)
{if(tree[k].l>r||tree[k].r<l)return 0;if(tree[k].l>=l&&tree[k].r<=r)return tree[k].mmax;pushdown(k);return max(query(k<<1,l,r),query(k<<1|1,l,r));
}int main()
{
#ifndef ONLINE_JUDGE
//  freopen("data.in.txt","r",stdin);
//  freopen("data.out.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);while(scanf("%d%d",&n,&m)!=EOF){memset(c,0,sizeof(LL)*(n+5));for(int i=1;i<=n;i++)scanf("%lld",a+i);for(int i=1;i<=n;i++){scanf("%lld",b+i);add(i,b[i]);}build(1,0,n);while(m--){int op;scanf("%d",&op);if(op==1){LL x,y;scanf("%lld%lld",&x,&y);update(1,x,x,y-a[x]);a[x]=y;}else if(op==2){LL x,y;scanf("%lld%lld",&x,&y);update(1,x,n,b[x]-y);add(x,y-b[x]);b[x]=y;}else if(op==3){int x;scanf("%d",&x);printf("%lld\n",ask(x)+query(1,0,x));}}}return 0;
}

2020ICPC(小米邀请赛2) - Data Structure Problem(线段树+树状数组)相关推荐

  1. HDU - 7072 Boring data structure problem 双端队列 + 思维

    传送门 文章目录 题意: 思路: 题意: 你需要实现如下四个操作 q≤1e7q\le1e7q≤1e7 思路: 做的时候想了个链表的思路让队友写了,懒. 看了题解感觉题解还是很妙的. 你需要快速插入一个 ...

  2. 【HDU - 4217 】Data Structure? (线段树求第k小数)

    题干: Data structure is one of the basic skills for Computer Science students, which is a particular w ...

  3. 2020ICPC(小米邀请赛1) - Phone Network(线段树优化递推)

    题目链接:点击查看 题目大意:给出一个长度为 n 的数列,每个数的取值范围是 [ 1 , m ],题目保证了每个数至少出现过一次,现在对于 i ∈ [ 1 , m ] ,分别输出在原数列中,包含了 [ ...

  4. 2020ICPC(小米邀请赛2) - Knapsack(贪心+dp)

    题目链接:点击查看 题目大意:给出 n 个物品,每个物品都有体积和价值,现在问容量为 m 的背包最多可以装下多少价值的物品 题目分析:本题正解应该是斜率优化dp,然鹅看了大佬们的博客讲解后,感觉不是自 ...

  5. 2020ICPC(小米邀请赛2) - 2020(二分+贪心)

    题目链接:点击查看 题目大意:给出一个长度为 n 的字符串,问最多可以匹配多少个互不相交的 "2020" 的子序列 题目分析:考虑 "2020" 是由两个 &q ...

  6. Data Structure Problem

    试题链接 题目描述 题意: 有两个序列, 操作1是将a序列的第x位改成y 操作2是将b序列的第x位改成y 操作3是找到一个cx,满足递推式c0=0,ci = max(ci-1+bi,ai) 题解: 官 ...

  7. Boring data structure problem 模拟-双端队列

    题意 : 维护一个"双端队列",1e7次操作,支持左插入,右插入,按值删除,查找中点(靠右)值ceil[(m+1)/2]ceil[(m + 1) / 2]ceil[(m+1)/2] ...

  8. HDU - 6967 G I love data structure 线段树维护矩阵 + 细节

    传送门 文章目录 题意: 思路: 题意: 给你两个长度为nnn的数组a,ba,ba,b,你需要完成如下四种操作: 思路: 思路还是比较简单的,首先建一颗线段树,线段树中维护a,b,a2,b2,aba, ...

  9. CF data structure 自制题单(一)

    CF data structure 2000~2100 为你的战斗,献上雷鸣般的喝彩!--唔姆 目标 30 道题 1. Problem - 1555E - Codeforces 看了提示 给一些线段, ...

最新文章

  1. python发明者叫什么-python是谁发明的
  2. 完全背包问题从简单到复杂
  3. Bootstrap组件_导航
  4. 关于flex布局的深入学习
  5. delphi webbrowser 对象不支持_建模初学者,那些你可能还不知道的10个ZBrush小技巧!【值得收藏】...
  6. Android MultiAutoCompleteTextView多文本输入提示
  7. tableview cell自适应撑高
  8. linux之systemctl命令
  9. syslinux下载链接
  10. NVIDIA-cuda-cudnn下载地址
  11. 结合插件实现【IDM+百度网盘】高速下载
  12. 菠萝来啦。新一代VueX 来啦 他有一个特别甜的名字“Pinia”,再不学你就out了【 Pinia/Vuex5中文文档】
  13. easypoi 语法_请问英语如何学习语法?
  14. c++map自动排序特性
  15. MT8516处理器简介—MT8516芯片技术资料解析
  16. 优化网络方法思维导图总结
  17. svn在本地搭建服务器,自己可以访问,局域网的其他电脑不可以访问
  18. ArcGIS API for JavaScript 开发笔记
  19. What is Java thread priority? 什么是java线程优先级
  20. 程序员去美国工作:工作在加州的华为

热门文章

  1. 惯性制导精度是多少_我国东风41精度凭啥第一?激光陀螺仪不算啥,太空水漂才真厉害...
  2. 什么是事务、半事务消息?怎么实现的?
  3. kafka server 参数解释
  4. 通道Channel-使用NIO 写入数据
  5. BeanFactory 和ApplicationContext 有什么区别?
  6. 字节流复制文本文件【应用】
  7. 初始化方法-使用参数设置属性初始值
  8. postgresql主从备份_PostgreSQL主从流复制与手动主备切换架构
  9. Servlet的第一个程序HelloWorld
  10. 深度学习原理与框架-卷积网络细节-数据增强策略 1.翻转 2.随机裁剪 3.平移 4.旋转角度...