P2042 [NOI2005]维护数列
题目的链接
众多平衡树独爱fhq
题目
有好多种操作:
1、添加一堆数
2、删除一个区间里的数
3、把一个区间里的数全变成同一个数
4、反转一个区间
5、求区间和
6、求最大的连续子序列的和。
因为要求连续的子序列的和,就想到了线段树区间合并。
这个,,应该可以想到。
所以就维护 lnum,rnum,num
做的时候的zz问题
崩溃了~~ 做的时候 我tmd 崩溃了,, 快神经了啊 我
一、添加一堆数我刚开始一个一个添加,, 因为方便(tle)
二、反转一个区间的时候没有反转lnum,rnum 这个问题很愚蠢,很快找到bug
三、update的时候没有判断左右子树是否存在。
四、空间不够用,没有弄回收节点的东西。
五、题意理解错了,一直卡一个点。最大的连续子序列的和不能不选,至少选一个数。wtmd一直以为可以不选,就是0。wtmdzz死了。
———————————假装分界线—————————————————
第一个问题好说,,用添加的点O(num)建一棵树再合并就好了。
第四个问题,删除的时候用一个栈存一下删除的节点,然后就好了。记得初始化!!!! 初始化回收的那个节点。。 不然wa爆你!!!!!
第五个问题,主要是意识不到,,还是看了别人的代码才发现的,在题解区里看到跟我代码差不多的巨巨,,不然我就wa到明年了。
———————————假装分界线—————————————————
于是,上面的都改完还tle。。。
这就真的自闭了,,就差一点点,, 一丁点。。
于是,心态崩了,又交了一发原来的代码,就ac了。。。 可能因为随机数的问题?
好tmd搞心态啊。
代码
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <string>
#include <queue>
#include <cstring>
#include <stack>
#include <map>
#include <bitset>
#include <set>
#include <unordered_set>
#include <climits>
using namespace std;
typedef long long ll;
typedef pair<int,ll> pii;
typedef pair<ll,ll> pll;
typedef pair<double,double> pdd;
typedef unsigned long long ull;
typedef unordered_set<int>::iterator sit;
#define st first
#define sd second
#define mkp make_pair
#define pb push_back
void tempwj(){
freopen("hash.in","r",stdin);freopen("hash.out","w",stdout);}
ll gcd(ll a,ll b){
return b == 0 ? a : gcd(b,a % b);}
ll qpow(ll a,ll b,ll mod){
a %= mod;ll ans = 1;while(b > 0){
if(b & 1)ans = ans * a % mod;a = a * a % mod;b >>= 1;}return ans;}
struct cmp{
bool operator()(const pii & a, const pii & b){
return a.second > b.second;}};
int lb(int x){
return x & -x;}
//friend bool operator < (Node a,Node b) 重载
const int inf = INT_MAX;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9+7;
const int maxn = 5e5+10;
const int M = 1e6 + 2;
// std::mt19937 rnd(233);
struct Node
{
int l,r,key;
int siz;
int val; // 当前节点的值
int lnum,rnum,num; // zuo you 最大连续
int sum;
int tag;
int tagf;
int f;
}node[maxn];
int cnt = 0;
int root = 0;
int sta[maxn];
int pos = 0;
int newnode(int val)
{
int p = 0;
if(pos >= 1)
{
p = sta[pos -- ];
// printf("%d 11111111\n",p);
}
else
p = ++cnt;
node[p].l = 0;
node[p].r = 0;
node[p].f = 0;
node[p].tagf = 0;
node[p].tag = 0;
node[p].val = val;
node[p].siz = 1;
node[p].key = rand();
// printf("%d\n",node[cnt].key);
node[p].lnum = node[p].rnum = node[p].num = max(val,0);
node[p].sum = val;
return p;
}
void update(int no)
{
if(node[no].l && node[no].r)
{
node[no].lnum = max(node[node[no].l].lnum,node[node[no].l].sum + node[no].val + node[node[no].r].lnum);
node[no].rnum = max(node[node[no].r].rnum,node[node[no].r].sum + node[no].val + node[node[no].l].rnum);
node[no].num = max(node[node[no].l].num,node[node[no].r].num);
node[no].num = max(node[no].num,node[node[no].l].rnum + node[node[no].r].lnum + node[no].val);
node[no].sum = node[node[no].l].sum + node[node[no].r].sum + node[no].val;
node[no].siz = node[node[no].l].siz + node[node[no].r].siz + 1;
}
else if(node[no].l)
{
node[no].lnum = max(node[node[no].l].lnum,node[no].val + node[node[no].l].sum);
node[no].rnum = max(0,node[no].val + node[node[no].l].rnum);
node[no].num = max(node[node[no].l].num,node[node[no].l].rnum + node[no].val);
node[no].sum = node[node[no].l].sum + node[no].val;
node[no].siz = node[node[no].l].siz + 1;
}
else if(node[no].r)
{
node[no].lnum = max(node[no].val + node[node[no].r].lnum, 0);
node[no].rnum = max(node[node[no].r].rnum,node[no].val + node[node[no].r].sum);
node[no].num = max(node[node[no].r].num,node[node[no].r].lnum + node[no].val);
node[no].sum = node[node[no].r].sum + node[no].val;
node[no].siz = node[node[no].r].siz + 1;
}
else
{
node[no].lnum = max(0,node[no].val);
node[no].rnum = max(0,node[no].val);
node[no].num = node[no].val;
node[no].sum = node[no].val;
node[no].siz = 1;
}
}
void Gai(int no,int num)
{
node[no].sum = node[no].siz * num;
node[no].val = num;
node[no].lnum = node[no].rnum = max(0,node[no].sum);
node[no].num = max(node[no].sum,node[no].val);
node[no].tag = num;
node[no].f = 1;
}
void Gai2(int no)
{
swap(node[no].l,node[no].r);
swap(node[no].lnum,node[no].rnum);
node[no].tagf ^= 1;
}
void down(int no)
{
if(node[no].f)
{
if(node[no].l)
Gai(node[no].l,node[no].tag);
if(node[no].r)
Gai(node[no].r,node[no].tag);
node[no].f = 0;
node[no].tag = 0;
}
if(node[no].tagf)
{
if(node[no].l)
Gai2(node[no].l);
if(node[no].r)
Gai2(node[no].r);
node[no].tagf = 0;
}
}
void split(int no,int& x,int& y,int siz)
{
if(no == 0)
{
x = 0;
y = 0;
return;
}
down(no);
if(node[node[no].l].siz + 1 <= siz)
{
x = no;
split(node[no].r,node[x].r,y,siz - node[node[no].l].siz - 1);
}
else
{
y = no;
split(node[no].l,x,node[no].l,siz);
}
update(no);
}
int merge(int x,int y)
{
if(x == 0 || y == 0)
return x + y;
if(node[x].key < node[y].key)
{
down(x);
node[x].r = merge(node[x].r,y);
update(x);
return x;
}
else
{
down(y);
node[y].l = merge(x,node[y].l);
update(y);
return y;
}
}
int a[maxn];
//模拟一个栈
int ss[maxn];
int build(int num)
{
int x = 0;
int last = 0;
int top = 0;
for (int i = 1; i <= num; i ++ )
{
x = newnode(a[i]);
last = 0;
while(top && node[ss[top]].key > node[x].key)
{
update(ss[top]);
last = ss[top];
ss[top -- ] = 0;
}
if(top)
{
node[ss[top]].r = x;
}
node[x].l = last;
ss[++top] = x;
}
while(top)
update(ss[top -- ]);
return ss[1];
}
void add(int pos,int num)
{
int x1,y1;
split(root,x1,y1,pos);
int t = build(num);
root = merge(x1,merge(t,y1));
}
void huishou(int no)
{
if(no == 0)
return;
sta[++pos] = no;
huishou(node[no].l);
huishou(node[no].r);
}
void del(int pos,int num)
{
int x1,y1;
split(root,x1,y1,pos);
int t;
split(y1,t,y1,num);
huishou(t);
root = merge(x1,y1);
}
void change(int l,int r,int num)
{
int x1,y1;
split(root,x1,y1,l - 1);
int x2,y2;
split(y1,x2,y2,r - l + 1);
if(x2)
Gai(x2,num);
root = merge(x1,merge(x2,y2));
}
void rev(int l,int r)
{
int x1,y1;
split(root,x1,y1,l - 1);
int x2,y2;
split(y1,x2,y2,r - l + 1);
if(x2)
Gai2(x2);
root = merge(x1,merge(x2,y2));
}
void zxbl(int no)
{
if(no == 0)
return;
zxbl(node[no].l);
printf("%d ",node[no].val);
zxbl(node[no].r);
}
int get_s(int l,int r)
{
int x1,y1;
split(root,x1,y1,l - 1);
int x2,y2;
split(y1,x2,y2,r - l + 1);
// zxbl(x2);
// printf("\n");
int ans = node[x2].sum;
root = merge(x1,merge(x2,y2));
return ans;
}
int main()
{
// tempwj();
int n,m;
scanf("%d%d",&n,&m);
for (int i = 1; i <= n; i ++ )
{
scanf("%d",&a[i]);
}
add(0,n);
// zxbl(root);
// printf("\n");
while(m -- )
{
char t[15];
scanf("%s",t + 1);
if(t[1] == 'G')
{
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",get_s(x,x + y - 1));
}
else if(t[1] == 'M' && t[3] == 'X')
{
printf("%d\n",node[root].num);
}
else if(t[1] == 'I')
{
int pos,p;
scanf("%d%d",&pos,&p);
for (int i = 1; i <= p; i ++ )
scanf("%d",&a[i]);
add(pos,p);
}
else if(t[1] == 'D')
{
int pos,p;
scanf("%d%d",&pos,&p);
del(pos - 1,p);
}
else if(t[1] == 'M' && t[3] == 'K')
{
int l,r,x;
scanf("%d%d%d",&l,&r,&x);
change(l,r + l - 1,x);
}
else if(t[1] == 'R')
{
int l,r;
scanf("%d%d",&l,&r);
rev(l,r + l - 1);
}
// zxbl(root);
// printf("%d\n",m);
}
}