[洛谷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;
}
posted @ 2022-04-12 16:38  皮皮刘  阅读(30)  评论(0编辑  收藏  举报