求助 WA 0pts
查看原帖
求助 WA 0pts
392830
zhengbinkang楼主2022/7/7 20:22

蒟蒻求助

具体是想着每一个节点储存首项和公差,从而就能计算出sum...
然鹅

0pts

对拍过,我是错的(废话) 但是瞪不出来哪里有问题

#include<iostream>
#define maxn 100005
#define ll long long
using namespace std;
int n, m;
struct node{
	ll l, r, sum, k, d;
}T[maxn*4];
ll a[maxn];
void build(ll u, ll l, ll r)//构建线段树 
{
	T[u].l = l; T[u].r = r;
	if(l == r)
	{
		T[u].sum = a[l];
	}
	else
	{
		ll mid = l + r >> 1;
		build(u<<1, l, mid);
		build((u<<1)+1, mid+1, r);
		T[u].sum = T[u<<1].sum + T[(u<<1)+1].sum;
	}
}
void pushdown(ll u)//下放
{
	
	int n1 = T[u<<1].r - T[u<<1].l + 1, 
	n2 = T[(u<<1)+1].r - T[(u<<1)+1].l + 1,
	k = T[u].k, d = T[u].d;
	
	T[u<<1].k += T[u].k;
	T[(u<<1)+1].k += T[u].k + (n1-1)*d;
	T[u<<1].d += T[u].d;
	T[(u<<1)+1].d += T[u].d;
	
	T[u<<1].sum += n1 * (k*2 + d*(n1-1)) / 2;
	T[(u<<1)+1].sum += (2*k + (2*n1 + n2 - 2)*d) * n2 / 2;
	
	T[u].k = 0; T[u].d = 0;//接触当前节点的tag状态,因为当前节点的tag状态已经不正确了
	
}
void modify(ll u, ll l, ll r, ll k, ll d)//在u节点让l~r的数字都加v
{
	if(l == T[u].l && r == T[u].r)//完全包含,不用往下调了 
	{
		T[u].k += k;
		T[u].d += d;
		T[u].sum += 
		(T[u].r - T[u].l + 1)
		* (k*2 + d * (T[u].r - T[u].l))/2;
//		cout << "k:" << k << ",d:" << d << endl;
//		cout << "n:" << (T[u].r - T[u].l + 1) << ",sum:" << (T[u].r - T[u].l + 1)
//		* (k*2 + d * (T[u].r - T[u].l))/2 << endl;
		return;
	}
	pushdown(u);//把上一轮的tag下调
	
	ll mid = (T[u].l + T[u].r) >> 1;
	if(r <= mid)
		modify(u<<1, l, r, k, d);
	else if(l >= mid+1)
		modify((u<<1)+1, l, r, k, d);
	else
	{
		modify(u<<1, l, mid, k, d);
		modify((u<<1)+1, mid+1, r, k+(mid-l+1)*d, d);
	}
	
	T[u].sum = T[u<<1].sum + T[(u<<1) + 1].sum;//重新调整该节点的sum值,使当前sum是正确的
}
ll query(ll u, ll l, ll r)
{
	if(T[u].l == l && T[u].r == r)
		return T[u].sum;
	ll mid = (T[u].l + T[u].r) >> 1;
	pushdown(u);
	if(r <= mid)
		return query(u<<1, l, r);
	else if(l >= mid+1)
		return query((u<<1)+1, l, r);
	else
		return query(u<<1, l, mid) + query((u<<1)+1, mid+1, r);
}

int main()
{
	freopen("1919810.in", "r", stdin);
	cin >> n >> m;
	for(ll i = 1; i <= n; i++) cin >> a[i];
	build(1, 1, n);
	ll op, t1, t2, t3, t4;
	for(int i = 1; i <= m; i++)
	{
		cin >> op;
		if(op == 1)
		{
			cin >> t1 >> t2 >> t3 >> t4;
			modify(1, t1, t2, t3, t4);
		}
		if(op == 2)
		{
			cin >> t1;
			cout << query(1, t1, t1) << endl;
		}
	}
	return 0;
}

(大佬勿喷) 大佬请喷,长点记性

2022/7/7 20:22
加载中...