这道题题目简洁新颖,吸引读者阅读兴趣...

题目

原题目

点这里

简要题目

需要你维护长度为n的序列并支持下列操作:

  1. 区间加法;
  2. 区间赋值;
  3. 区间每个 \(a_i\) 变成 \(\max⁡(a_i-t,0)\);
  4. 单点询问值
  5. 单点询问历史最大值

\(n,m≤500000\),其中 \(m\) 为操作数。

正解

首先考虑,如果这道题没有历史版本我们该怎么做?

其实很简单,这里我就不赘述了 其实是我懒得说 。

那么我们考虑,对于这个 \(5\) 操作,我们应该怎么做?

首先,分析 \(3\) 操作,这是一个很特殊的操作。

对于每个 \(a_i\) ,将 \(a_i\) 修改为 \(\max(a_i-t,0)\),我们把它写成函数,即

\[f(x)=\max(x-t,0)
\]

写成一般形式,即

\[f(x)=\max(x+a,b)
\]

那么,我们可以轻松地画出这个函数的图像:

考虑能否将两个函数 \(f_1(x),f_2(x)\) 的最大值全部合并,成为 \(g(x)\),即如下图

显然是可行的,具体如何实现请自行思考,如果实在不行,看看代码也好啊。

现在,我们来看这样的函数能不能叠加,即对于 \(f(x)=\max(x+a,b)\),能不能给 \(a+\Delta\) 或者 \(b+\Delta\)。

显然这也是可行的,即新的 \(f'(x)=\max(x+a+\Delta,b)\) 或者是 \(f'(x)=\max(x+a,b+\Delta)\)。

发现这个函数有叠加性以及能够维护函数最大,发现似乎可以用这样的函数来做这道题,但是,需要对我们的操作进行一些变换:

设标记 \((a,b)\) 表示将 \(x\) 变成 \(\max⁡(a+x,b)\) 。

  • 区间加上 \(a\):\((a,-\infty)\);

  • 区间赋值为 \(a\):\((-\infty,a)\);

  • 区间每个 \(x\) 变成 \(\max⁡(x-a,0):(-a,0)\);

  • 合并 \((a,b)\) 与 \((c,d)\):\((a+c,\max⁡(b+c,d))\);

假设对一个位置作用的标记对应函数依次为 \(f_1 (x),f_2 (x)\ldots,f_k (x)\)

历史最大值对应函数为 \(\max\{x,f_1 (x),f_2(f_1(x)),……,f_k (f_{k-1}(……f_1(x)))\}\)

如若能维护出该函数,历史最大值即可维护出。

可以发现将两个这样函数取 \(\max\) 后仍然是一个形式一样的函数(见上面的图)。于是历史最大值的函数即可维护。用线段树在每个区间维护当前标记的函数和历史最大值的函数即可,这两个都支持 \(\mathcal O(1)\) 合并。于是复杂度为 \(\mathcal O(n\log⁡n)\)。

#include<cstdio>

#define rep(i,__l,__r) for(signed i=__l,i##_end_=__r;i<=i##_end_;++i)
#define fep(i,__l,__r) for(signed i=__l,i##_end_=__r;i>=i##_end_;--i)
#define writc(a,b) fwrit(a),putchar(b)
#define mp(a,b) make_pair(a,b)
#define ft first
#define sd second
#define LL long long
#define ull unsigned long long
#define uint unsigned int
#define pii pair< int,int >
#define Endl putchar('\n')
// #define FILEOI
#define int long long
// #define int unsigned #ifdef FILEOI
# define MAXBUFFERSIZE 500000
inline char fgetc(){
static char buf[MAXBUFFERSIZE+5],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXBUFFERSIZE,stdin),p1==p2)?EOF:*p1++;
}
# undef MAXBUFFERSIZE
# define cg (c=fgetc())
#else
# define cg (c=getchar())
#endif
template<class T>inline void qread(T& x){
char c;bool f=0;
while(cg<'0'||'9'<c)f|=(c=='-');
for(x=(c^48);'0'<=cg&&c<='9';x=(x<<1)+(x<<3)+(c^48));
if(f)x=-x;
}
inline int qread(){
int x=0;char c;bool f=0;
while(cg<'0'||'9'<c)f|=(c=='-');
for(x=(c^48);'0'<=cg&&c<='9';x=(x<<1)+(x<<3)+(c^48));
return f?-x:x;
}
template<class T,class... Args>inline void qread(T& x,Args&... args){qread(x),qread(args...);}
template<class T>inline T Max(const T x,const T y){return x>y?x:y;}
template<class T>inline T Min(const T x,const T y){return x<y?x:y;}
template<class T>inline T fab(const T x){return x>0?x:-x;}
inline int gcd(const int a,const int b){return b?gcd(b,a%b):a;}
inline void getInv(int inv[],const int lim,const int MOD){
inv[0]=inv[1]=1;for(int i=2;i<=lim;++i)inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;
}
template<class T>void fwrit(const T x){
if(x<0)return (void)(putchar('-'),fwrit(-x));
if(x>9)fwrit(x/10);
putchar(x%10^48);
}
inline LL mulMod(const LL a,const LL b,const LL mod){//long long multiplie_mod
return ((a*b-(LL)((long double)a/mod*b+1e-8)*mod)%mod+mod)%mod;
} const int MAXN=5e5;
const int INF=0x3f3f3f3f3f3f3f3fll; int n,m,val[MAXN+5]; int a[(MAXN<<2)+5][2],b[(MAXN<<2)+5][2];
//a[i][0],b[i][0]:维护当前的 a,b , 若 i 不是叶节点, 那么这就是懒标记
//a[i][1],b[i][1]:维护历史最大版本 #define lc (i<<1)
#define rc (i<<1|1)
#define fff (i>>1)
#define MID ((l+r)>>1)
#define LEQ lc,l,MID
#define REQ rc,MID+1,r inline void upd(const int i){
a[i][1]=Max(a[i][1],a[i][0]+a[fff][1]);
b[i][1]=Max(b[i][1],Max(b[i][0]+a[fff][1],b[fff][1]));
a[i][0]=Max(a[i][0]+a[fff][0],-INF),b[i][0]=Max(b[i][0]+a[fff][0],b[fff][0]);
} inline void pushdown(const int i){
upd(lc),upd(rc);
a[i][0]=a[i][1]=0,b[i][0]=b[i][1]=-INF;
} void modify(const int i,const int l,const int r,const int L,const int R,const int c,const int d){
if(L<=l && r<=R){
a[i][1]=Max(a[i][1],a[i][0]+c);
b[i][1]=Max(b[i][1],Max(b[i][0]+c,d));
a[i][0]=Max(a[i][0]+c,-INF),b[i][0]=Max(b[i][0]+c,d);
return;
}
pushdown(i);
if(L<=MID)modify(LEQ,L,R,c,d);
if(MID<R)modify(REQ,L,R,c,d);
} int query(const int i,const int l,const int r,const int p,const int o){
if(l==r)return Max(val[p]+a[i][o],b[i][o]);
pushdown(i);
if(p<=MID)return query(LEQ,p,o);
else return query(REQ,p,o);
} signed main(){
#ifdef FILEOI
freopen("file.in","r",stdin);
freopen("file.out","w",stdout);
#endif
qread(n,m);
rep(i,1,n)qread(val[i]);
int t,l,r,x;
while(m--){
qread(t,l);
if(t<=3){
qread(r,x);
if(t==1)modify(1,1,n,l,r,x,-INF);
else if(t==2)modify(1,1,n,l,r,-x,0);
else modify(1,1,n,l,r,-INF,x);
}
else writc(query(1,1,n,l,t-4),'\n');
}
return 0;
}

「题解」「UOJ-164」「清华集训2015」V的更多相关文章

  1. UOJ#164:【清华集训2015】V

    浅谈区间最值操作与历史最值问题:https://www.cnblogs.com/AKMer/p/10225100.html 题目传送门:http://uoj.ac/problem/164 论文题.论文 ...

  2. 「清华集训2015」V

    「清华集训2015」V 题目大意: 你有一个序列,你需要支持区间加一个数并对 \(0\) 取 \(\max\),区间赋值,查询单点的值以及单点历史最大值. 解题思路: 观察发现,每一种修改操作都可以用 ...

  3. UOJ #164. 【清华集训2015】V | 线段树

    题目链接 UOJ #164 题解 首先,这道题有三种询问:区间加.区间减(减完对\(0\)取\(\max\)).区间修改. 可以用一种标记来表示--标记\((a, b)\)表示把原来的值加上\(a\) ...

  4. 2018.07.28 uoj#164. 【清华集训2015】V(线段树)

    传送门 线段树好题. 要求支持的操作: 1.区间变成max(xi−a,0)" role="presentation" style="position: rela ...

  5. UOJ #164 【清华集训2015】 V

    题目链接:V 这道题由于是单点询问,所以异常好写. 注意到每种修改操作都可以用一个标记\((a,b)\)表示.标记\((a,b)\)的意义就是\(x= \max\{x+a,b\}\) 同时这种标记也是 ...

  6. @uoj - 164@ 【清华集训2015】V

    目录 @description@ @solution@ @accepted code@ @details@ @description@ Picks博士观察完金星凌日后,设计了一个复杂的电阻器.为了简化 ...

  7. LOJ 164 【清华集训2015】V——线段树维护历史最值

    题目:http://uoj.ac/problem/164 把操作改成形如 ( a,b ) 表示加上 a 之后对 b 取 max 的意思. 每个点维护当前的 a , b ,还有历史最大的 a , b 即 ...

  8. [LOJ#2330]「清华集训 2017」榕树之心

    [LOJ#2330]「清华集训 2017」榕树之心 试题描述 深秋.冷风吹散了最后一丝夏日的暑气,也吹落了榕树脚下灌木丛的叶子.相识数年的Evan和Lyra再次回到了小时候见面的茂盛榕树之下.小溪依旧 ...

  9. [LOJ#2329]「清华集训 2017」我的生命已如风中残烛

    [LOJ#2329]「清华集训 2017」我的生命已如风中残烛 试题描述 九条可怜是一个贪玩的女孩子. 这天她在一堵墙钉了 \(n\) 个钉子,第 \(i\) 个钉子的坐标是 \((x_i,y_i)\ ...

随机推荐

  1. 843. n-皇后问题(dfs+输出各种情况)

    n-皇后问题是指将 n 个皇后放在 n∗n 的国际象棋棋盘上,使得皇后不能相互攻击到,即任意两个皇后都不能处于同一行.同一列或同一斜线上. 现在给定整数n,请你输出所有的满足条件的棋子摆法. 输入格式 ...

  2. F 采蘑菇的克拉莉丝

    这是一道树链剖分的题目: 很容易想到,我们在树剖后,对于操作1,直接单点修改: 对于答案查询,我们直接的时候,我们假设查询的点是3,那么我们在查询的时候可分为两部分: 第一部分:查找出除3这颗子树以外 ...

  3. 《NVM-Express-1_4-2019.06.10-Ratified》学习笔记(8.7)Standard Vendor Specific Command Format

    8.7 Standard Vendor Specific Command Format 标准的厂商特定命令格式 Controller可以支持Figure 106中定义的标准的Vendor Specif ...

  4. 虚拟机中的CentOS 7设置固定IP连接最理想的配置(转载)

    来源:虚拟机中的CentOS 7设置固定IP连接最理想的配置(https://my.oschina.net/panhongju/blog/826814) 转载说明:这是我看了很多篇虚拟机静态IP配置写 ...

  5. H3C虚拟化技术

    一.IRF简单介绍 IRF(Intelligent Resilient Framework,智能弹性架构)是H3C自主研发的软件虚拟化技术.它的核心思想是将多台设备连接在一起,进行必要的配置后,虚拟化 ...

  6. CSS伪类before,after制作左右横线中间文字效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. php设计模式之桥接模式实例代码

    <?php header("Content-type:text/html;charset=utf-8"); abstract class msg{ protected $se ...

  8. Mahmoud and Ehab and the message

    Mahmoud wants to send a message to his friend Ehab. Their language consists of n words numbered from ...

  9. FactoryBean的作用

    Spring 中有两种类型的Bean,一种是普通Bean,另一种是工厂Bean 即 FactoryBean.FactoryBean跟普通Bean不同,其返回的对象不是指定类的一个实例,而是该Facto ...

  10. 以POST方式发送

    URL url = null; String inputLine = null; HttpURLConnection httpurlconnection = null; try { //取上级电警平台 ...