有关此题的数组调用效率
查看原帖
有关此题的数组调用效率
234224
青鸟_Blue_Bird楼主2020/5/5 18:10

我参考了部分第一篇题解当然不是抄的

然而我的时间效率平均每个点比题解慢了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;
}
2020/5/5 18:10
加载中...