总之就是 | 洛谷 P1253 [yLOI2018] 扶苏的问题
单纯的和洛谷博客同步一下。
「思路简述」
一道比较板的线段树吧,比较适合新手拿来练手。
题意非常清楚了,简单来说就是需要一种支持区间查询和区间修改的数据结构,那么很自然的就能想到用线段树来解决。
因为有两种区间修改的操作,所以我们需要两个 Tag,下传的操作和正常的区间加没有太多区别,只不过需要注意在下传时,要先传 Cover 操作再下传 Add 操作。
「Code」
因为每次操作的 \(x \le 10^9\),所以注意要开 long long
和 INF
值的大小。
前面的学长提供了指针的写法,我这里则是相对普通的数组写法。
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cstring>
#define lc(x) (x<<1)
#define rc(x) (x<<1|1)
#define Heriko return
#define Deltana 0
#define Romanno 1
#define S signed
#define LL long long
#define R register
#define I inline
#define CI const int
#define mst(a, b) memset(a, b, sizeof(a))
#define ON std::ios::sync_with_stdio(false);cin.tie(0)
#define Files() freopen("RNMTQ.in","r",stdin);freopen("RNMTQ.out","w",stdout)
using namespace std;
template<typename J>
I void fr(J &x)
{
short f(1);x=0;char c=getchar();
while(c<'0' or c>'9')
{
if(c=='-') f=-1;
c=getchar();
}
while (c>='0' and c<='9')
{
x=(x<<3)+(x<<1)+(c^=48);
c=getchar();
}
x*=f;
}
template<typename J>
I void fw(J x,bool k)
{
if(x<0) x=-x,putchar('-');
static short stak[35];short top(0);
do
{
stak[top++]=x%10;
x/=10;
}
while(x);
while(top) putchar(stak[--top]+'0');
k?puts(""):putchar(' ');
}
template<typename J>
I J Hmax(const J &x,const J &y) {Heriko x>y?x:y;}
const LL MXX(1e6+1),INF(1e12);
int n,q;
struct Node
{
int l,r;LL mx,tg1,tg2;
}
t[MXX<<2];
I void Pushup(int x) {t[x].mx=Hmax(t[lc(x)].mx,t[rc(x)].mx);}
I void Pushdown(int x)
{
if(t[x].tg2!=INF)
{
t[lc(x)].tg1=0;
t[lc(x)].tg2=t[x].tg2;
t[lc(x)].mx=t[x].tg2;
t[rc(x)].tg1=0;
t[rc(x)].tg2=t[x].tg2;
t[rc(x)].mx=t[x].tg2;
t[x].tg2=INF;
}
if(t[x].tg1)
{
t[lc(x)].tg1+=t[x].tg1;
t[lc(x)].mx+=t[x].tg1;
t[rc(x)].tg1+=t[x].tg1;
t[rc(x)].mx+=t[x].tg1;
t[x].tg1=0;
}
}
void Build(int x,int l,int r)
{
t[x].l=l,t[x].r=r;t[x].mx=t[x].tg1=0;t[x].tg2=INF;
if(l==r)
{
fr(t[x].mx);
Heriko;
}
int mid((l+r)>>1);
Build(lc(x),l,mid);Build(rc(x),mid+1,r);
Pushup(x);
}
void ModifyAdd(int x,int lx,int rx,LL v)
{
if(lx<=t[x].l and t[x].r<=rx)
{
t[x].tg1+=v;t[x].mx+=v;
Heriko;
}
Pushdown(x);
int mid((t[x].l+t[x].r)>>1);
if(lx<=mid) ModifyAdd(lc(x),lx,rx,v);
if(rx>mid) ModifyAdd(rc(x),lx,rx,v);
Pushup(x);
}
void ModifyChange(int x,int lx,int rx,LL v)
{
if(lx<=t[x].l and t[x].r<=rx)
{
t[x].tg1=0;t[x].tg2=v;t[x].mx=v;
Heriko;
}
Pushdown(x);
int mid((t[x].l+t[x].r)>>1);
if(lx<=mid) ModifyChange(lc(x),lx,rx,v);
if(rx>mid) ModifyChange(rc(x),lx,rx,v);
Pushup(x);
}
LL Query(int x,int lx,int rx)
{
if(lx<=t[x].l and t[x].r<=rx) Heriko t[x].mx;
LL res(-INF);int mid((t[x].l+t[x].r)>>1);
Pushdown(x);
if(lx<=mid) res=Hmax(Query(lc(x),lx,rx),res);
if(rx>mid) res=Hmax(Query(rc(x),lx,rx),res);
Heriko res;
}
S main()
{
fr(n),fr(q);Build(1,1,n);
while(q--)
{
int opt,l,r;LL x;
fr(opt),fr(l),fr(r);
if(opt==1) fr(x),ModifyChange(1,l,r,x);
else if(opt==2) fr(x),ModifyAdd(1,l,r,x);
else fw(Query(1,l,r),1);
}
Heriko Deltana;
}
如有错误之处请各位大佬及时指出。
Do you like WHAT YOU SEE ?