只WA了第一个点求助
查看原帖
只WA了第一个点求助
306962
MVP_Harry楼主2020/9/3 11:30

RT,评测记录如下戳我。按理这种线段树的题,过了九个点,这个点也过了66次询问,而且全是大数据,出现这种情况就很糟糕啊。

思路不知道和题解一不一样,因为是等差数列,所以我考虑维护这个线段的首项和公差,这样就可以快速地pushdown。代码有注释,码风不错,求大佬帮忙,谢谢!

ll A[maxn], N, Q; //数组

struct SegmentTree {
	ll x, start, comdif;
} T[maxn << 2]; //segment tree的和,这个线段的lazy tag -> 数列的首项,数列的公差

//建树
void build(ll s, ll t, ll p) { 
	if (s == t) {
		T[p].x = A[s];
		return ;
	}
	ll m = (s + t) >> 1;
	build(s, m, p << 1), build(m + 1, t, p << 1 | 1);
	T[p].x = T[p << 1].x + T[p << 1 | 1].x;
}

//pushdown操作
void pushdown(ll s, ll t, ll p) {
	ll m = (s + t) >> 1;
	T[p << 1].start += T[p].start, T[p << 1 | 1].start += (T[p].start + T[p].comdif * (m + 1 - s)); //首项 + 线段对应的首项
	T[p << 1].comdif += T[p].comdif, T[p << 1 | 1].comdif += T[p].comdif; //公差相加
	T[p << 1].x += (T[p].start * 2 + T[p].comdif * (m - s)) * (m - s + 1) / 2; //第一个子线段求和
	T[p << 1 | 1].x += (T[p].start + T[p].comdif * (m + 1 - s) + T[p].start + T[p].comdif * (t - s)) * (t - m) / 2; //第二个子线段求和
	T[p].start = 0, T[p].comdif = 0; //清零
}

void update(ll l, ll r, ll s, ll t, ll p, ll val, ll K) {  
	if (l <= s && r >= t) { 
		T[p].x += (K + val * (s - l) + K + (t - l) * val) * (t - s + 1) / 2; //K代表题目中的K,val是公差,给他加上去
		T[p].comdif += val; //公差更新
		T[p].start += (K + (s - l) * val); //首项更新
		return ;
	}
	ll m = (s + t) >> 1;
	if (T[p].start) pushdown(s, t, p); 
	if (l <= m) update(l, r, s, m, p << 1, val, K);
	if (r > m) update(l, r, m + 1, t, p << 1 | 1, val, K);
	T[p].x = T[p << 1].x + T[p << 1 | 1].x; 
}

ll query(ll l, ll s, ll t, ll p) { //单点查询
	if (s == t) return T[p].x;
	ll m = (s + t) >> 1;
	if (T[p].start) pushdown(s, t, p);
	if (l <= m) return query(l, s, m, p << 1);
	return query(l, m + 1, t, p << 1 | 1);
}

int main() {
	ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> N >> Q;
    for (ll i = 1; i <= N; i++) 
    	cin >> A[i];
    build(1, N, 1);
   	ll x, c1, c2, val, K;
   	while (Q--) {
   		cin >> x;
   		if (x == 1) { 
   			cin >> c1 >> c2 >> K >> val;
   			update(c1, c2, 1, N, 1, val, K);
   		}
   		else if (x == 2) {
   			cin >> c1;
   			cout << query(c1, 1, N, 1) << endl;
   		}
   	} 
	return 0;
}
2020/9/3 11:30
加载中...