我参考了部分第一篇题解当然不是抄的
然而我的时间效率平均每个点比题解慢了100ms
(用题解测了一下,望别介意)
所以我的程序是哪里慢了呢??
经过我反复对比,最大的不同似乎就是我用了宏定义,然后直接调用了很多son数组,而原题解则是选择了创建临时变量。问一下大佬们,这题的son数组调用挺多的,是因为数组调用慢的原因吗??
#include <bits/stdc++.h>
using namespace std;
#define N 1000010
const int INF = (int)2e9;
#define isdigit(c) ((c)>='0'&&(c)<='9')
#define max(a,b) ((a)>(b)?(a):(b))
#define swap(a,b) ((a)^=(b)^=(a)^=(b))
/*
int bug = 0;
inline void debug(){
bug++;
printf("bugnum: %d bug point? \n", bug);
return ;
}
*/
inline int read(){
int x = 0, s = 1;
char c = getchar();
while(!isdigit(c)){
if(c == '-') s = -1;
c = getchar();
}
while(isdigit(c)){
x = (x << 1) + (x << 3) + (c ^ '0');
c = getchar();
}
return x * s;
}
int root;
int a[N], siz[N], son[N][2], fa[N], id[N];
int lx[N], rx[N], mx[N], sum[N], v[N]; /*sum: zishu de quanzhi he*/
bool tag[N], rev[N];
queue <int> q;
#define lson son[o][0]
#define rson son[o][1]
/*可优化之处: 大量调用速度,程序变慢了。。。。。。*/
inline void pushup(int o){
sum[o] = sum[lson] + sum[rson] + v[o];
siz[o] = 1;
siz[o] += lson ? (rson ? siz[rson] : 0) + siz[lson] : (rson ? siz[rson] : 0);
mx[o] = max(mx[lson], max(mx[rson], rx[lson] + v[o] + lx[rson]));
lx[o] = max(lx[lson], sum[lson] + v[o] + lx[rson]);
rx[o] = max(rx[rson], sum[rson] + v[o] + rx[lson]);
return ;
}
inline void pushdown(int o){
if(tag[o]){
rev[o] = tag[o] = 0; /*has a new tag. The old one has no meaning*/
if(lson) tag[lson] = 1, v[lson] = v[o], sum[lson] = v[o] * siz[lson];
if(rson) tag[rson] = 1, v[rson] = v[o], sum[rson] = v[o] * siz[rson];
if(v[o] >= 0){
if(lson) lx[lson] = rx[lson] = mx[lson] = sum[lson];
if(rson) lx[rson] = rx[rson] = mx[rson] = sum[rson];
} else {
if(lson) lx[lson] = rx[lson] = 0, mx[lson] = v[o];
if(rson) lx[rson] = rx[rson] = 0, mx[rson] = v[o];
}
}
if(rev[o]){
rev[o] = 0;
rev[lson] ^= 1;
rev[rson] ^= 1; /*前后缀的上升子序列全部反过来了*/
swap(lx[lson], rx[lson]); swap(lx[rson], rx[rson]);
swap(son[lson][0], son[lson][1]); swap(son[rson][0], son[rson][1]);
}
return ;
}
void rotate(int o, int& k){
int f = fa[o], g = fa[f]; /*father and the grandfather*/
int c = son[f][1] == o;
if(f == k)k = o;
else son[g][f == son[g][1]] = o;
fa[o] = g; fa[f] = o; fa[son[o][c ^ 1]] = f;
son[f][c] = son[o][c ^ 1]; son[o][c ^ 1] = f; /*imagine the image in your mind*/
pushup(f);
return ;
}
void splay(int o, int& aim){
while(o != aim){
int f = fa[o], g = fa[f];
if(f != aim){
/*bug point!!*/
// son[g][0] == (f[son][0] ^ f == o) ? rotate(o, aim) : rotate(f, aim);
if(g) rotate(f, aim);
}
rotate(o, aim);
}
pushup(o);
if(!aim) root = o;
return ;
}
inline int find(int o, int rk){
pushdown(o);
if(siz[lson] + 1 == rk) return o;
if(siz[lson] >= rk) return find(lson, rk);
else return find(rson, rk - siz[lson] - 1);
}
inline void recycle(int o){
if(lson) recycle(lson);
if(rson) recycle(rson);
q.push(o);
fa[o] = lson = rson = tag[o] = rev[o] = 0;
return ;
}
inline int split(int k, int tot){
// debug();
int o = find(root, k), y = find(root, k + tot + 1);
splay(o, root); splay(y, rson);
return son[y][0];
}
/*find the [k + 1, k + tot + 1] and move x to root, y to the right son*/
inline void query(int k, int tot){
int o = split(k, tot);
// debug();
printf("%d\n", sum[o]);
return ;
}
inline void modify(int k, int tot, int val){
int x = split(k, tot), y = fa[x];
v[x] = val;
tag[x] = 1;
sum[x] = siz[x] * val;
if(val >= 0) lx[x] = rx[x] = mx[x] = sum[x];
else lx[x] = rx[x] = 0, mx[x] = val;
pushup(y); pushup(fa[y]);
return ;
}
inline void rever(int k, int tot){
int x = split(k, tot), y = fa[x];
if(!tag[x]){
rev[x] ^= 1;
swap(son[x][0], son[x][1]);
swap(lx[x], rx[x]);
pushup(y);
pushup(fa[y]);
}
return ;
}
inline void Delete(int k, int tot){
int x = split(k, tot), y = fa[x];
recycle(x);
son[y][0] = 0;
pushup(y);
pushup(fa[y]);
return ;
}
void build(int l, int r, int f){ /*build tree quickly*/
int mid = l + r >> 1, now = id[mid], pre = id[f];
if(l == r){
mx[now] = sum[now] = a[l];
tag[now] = rev[now] = 0;
lx[now] = rx[now] = max(a[l], 0);
siz[now] = 1;
}
if(l < mid) build(l, mid - 1, mid);
if(mid < r) build(mid + 1, r, mid);
v[now] = a[mid]; fa[now] = pre;
pushup(now);
son[pre][mid >= f] = now;
return ;
}
int cnt = 0;
void insert(int k, int tot){
for(int i = 1;i <= tot; i++) a[i] = read();
for(int i = 1;i <= tot; i++){
if(!q.empty())id[i] = q.front(), q.pop();
else id[i] = ++cnt;
}
build(1, tot, 0);
int z = id[(1 + tot) >> 1];
int o = find(root, k + 1), y = find(root, k + 2);/*the real number we nned*/
/*bug 1*/splay(o, root); splay(y, rson);//直接把插入的新树挂到右儿子的左儿子
fa[z] = y; son[y][0] = z;
pushup(y);
pushup(o);
return ;
}
int main(){
// freopen("hh.txt", "r", stdin);
int n = read(), m = read();
mx[0] = a[1] = a[n + 2] = -INF;
for(int i = 1;i <= n; i++) a[i + 1] = read();
for(int i = 1;i <= n + 2; i++) id[i] = i;
build(1, n + 2, 0);
root = (n + 2 + 1) >> 1;
cnt = n + 2;
char s[20];
while(m--){
int k, tot, val;
scanf("%s", s);
if(s[0] != 'M' || s[2] != 'X')k = read() , tot = read();
if(s[0] == 'I') insert(k, tot);
if(s[0] == 'D') Delete(k, tot);
if(s[0] == 'M'){
if(s[2] == 'X') printf("%d\n", mx[root]);
else val = read(), modify(k, tot, val);
}
if(s[0] == 'R') rever(k, tot);
if(s[0] == 'G') query(k, tot);
}
return orz;
}