[洛谷P2710] 数列
前言
裸得不能再裸的数据结构有啥要讲的?
我的名字叫 \(\tt FHQ\ Treap\),今年第一次被主人写,住在主人的树板博客里,未婚。我在数据结构店服务。每天都要加班到晚上 11 点才能回家。我不抽烟,酒仅止于浅尝。晚上 12 点睡,每天睡不够 8 个小时。睡前,我一定喝一杯温牛奶,然后做 20 分钟的 \(\rm split\) 操,上了床,马上熟睡。一觉到天亮,决不把疲劳和压力,留到第二天。主人都说我很正常。
真恶心,这是我写的?
题目
讲解
好像应该写题解来着?注意一些最大连续子序列和可能是负数,有些写法可能边界没处理好就只能输出 0。
代码
//12252024832524
#include <bits/stdc++.h>
#define TT template<typename T>
using namespace std;
typedef long long LL;
const int MAXN = 200005;
const int INF = 0x3f3f3f3f;
int n,m,tmpread[MAXN];
char opt[15];
LL Read()
{
LL x = 0,f = 1; char c = getchar();
while(c > '9' || c < '0'){if(c == '-') f = -1;c = getchar();}
while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
return x * f;
}
TT void Put1(T x)
{
if(x > 9) Put1(x/10);
putchar(x%10^48);
}
TT void Put(T x,char c = -1)
{
if(x < 0) putchar('-'),x = -x;
Put1(x); if(c >= 0) putchar(c);
}
TT T Max(T x,T y){return x > y ? x : y;}
TT T Min(T x,T y){return x < y ? x : y;}
TT T Abs(T x){return x < 0 ? -x : x;}
mt19937 myrand(time(0));
uniform_int_distribution<> gen(1,1000000000);
int getrand(){return gen(myrand);}
int rt,rb[MAXN],tot;
struct node{
int l,r,siz,val,lm,rm,mx,s,cv,rd;
bool rev;
}t[MAXN];
int newnode(int v){int ret = rb[tot--];t[ret] = node{0,0,1,v,v,v,v,v,INF,getrand(),0};return ret;}
void clr(int x){
rb[++tot] = x;
if(t[x].l) clr(t[x].l);
if(t[x].r) clr(t[x].r);
}
void up(int x){
t[x].siz = t[t[x].l].siz + t[t[x].r].siz + 1;
t[x].s = t[t[x].l].s + t[t[x].r].s + t[x].val;
t[x].lm = Max(t[t[x].l].lm,t[t[x].l].s+t[x].val+Max(0,t[t[x].r].lm));
t[x].rm = Max(t[t[x].r].rm,t[t[x].r].s+t[x].val+Max(0,t[t[x].l].rm));
t[x].mx = Max(t[t[x].l].mx,t[t[x].r].mx);
t[x].mx = Max(Max(t[x].lm,t[x].rm),t[x].mx);
t[x].mx = Max(t[x].mx,Max(0,t[t[x].l].rm)+t[x].val+Max(0,t[t[x].r].lm));
}
void Rev(int x){
if(!x) return;
swap(t[x].l,t[x].r);
swap(t[x].lm,t[x].rm);
t[x].rev ^= 1;
}
void Cover(int x,int v){
if(!x) return;
t[x].cv = t[x].val = v;
t[x].s = v * t[x].siz;
t[x].lm = t[x].rm = t[x].mx = Max(v,t[x].s);
}
void down(int x){
if(t[x].rev){Rev(t[x].l);Rev(t[x].r);t[x].rev = 0;}
if(t[x].cv != INF){Cover(t[x].l,t[x].cv);Cover(t[x].r,t[x].cv);t[x].cv = INF;}
}
int Build(int l,int r){
if(l > r) return 0;
if(l == r) {return newnode(tmpread[l]);}
int mid = (l+r) >> 1,ret = newnode(tmpread[mid]);
t[ret].l = Build(l,mid-1);
t[ret].r = Build(mid+1,r);
up(ret);
return ret;
}
void split(int now,int val,int &x,int &y){
if(!now){x = y = 0;return;}
else{
down(now);
if(t[t[now].l].siz + 1 <= val) x = now,split(t[now].r,val-t[t[now].l].siz-1,t[now].r,y);
else y = now,split(t[now].l,val,x,t[now].l);
up(now);
}
}
int mge(int x,int y){
if(!x || !y) return x | y;
if(t[x].rd < t[y].rd){down(x); t[x].r = mge(t[x].r,y); up(x); return x;}
else {down(y); t[y].l = mge(x,t[y].l); up(y); return y;}
}
int x,y,z;
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
t[0].lm = t[0].rm = t[0].mx = -INF;
while(tot < 200000) ++tot,rb[tot] = tot;
n = Read(); m = Read();
for(int i = 1;i <= n;++ i) tmpread[i] = Read();
rt = Build(1,n);
while(m --> 0){
scanf("%s",opt);
if(opt[0] == 'I'){//insert
int pos = Read(),len = Read();
for(int i = 1;i <= len;++ i) tmpread[i] = Read();
split(rt,pos,x,y);
rt = mge(mge(x,Build(1,len)),y);
}
else if(opt[0] == 'D'){//delete
int pos = Read(),len = Read();
split(rt,pos-1,x,y);
split(y,len,y,z);
clr(y);
rt = mge(x,z);
}
else if(opt[0] == 'R'){//reverse
int pos = Read(),len = Read();
split(rt,pos-1,x,y);
split(y,len,y,z);
Rev(y);
rt = mge(mge(x,y),z);
}
else if(opt[2] == 'K'){//make-same
int pos = Read(),len = Read();
split(rt,pos-1,x,y);
split(y,len,y,z);
Cover(y,Read());
rt = mge(mge(x,y),z);
}
else if(opt[0] == 'G' && strlen(opt) == 7){//get-sum
int pos = Read(),len = Read();
split(rt,pos-1,x,y);
split(y,len,y,z);
Put(t[y].s,'\n');
rt = mge(mge(x,y),z);
}
else if(opt[0] == 'G'){//get
int pos = Read();
split(rt,pos-1,x,y);
split(y,1,y,z);
Put(t[y].s,'\n');
rt = mge(mge(x,y),z);
}
else if(opt[2] == 'X'){//max-sum
int pos = Read(),len = Read();
split(rt,pos-1,x,y);
split(y,len,y,z);
Put(t[y].mx,'\n');
rt = mge(mge(x,y),z);
}
}
return 0;
}