qlog^2线段树求条
查看原帖
qlog^2线段树求条
1040902
Takanashi_Hina楼主2024/10/23 21:40

会关注的。

开int128前TLE后RE

longlong 前WA 后TLE

不管TLE了。

#include<bits/stdc++.h>
#define ll __int128
using namespace std;

const int N = 2e5 + 10;
struct seg{
	ll val;
	ll tag;
}t[N<<2];
ll a[N],n,W,q,pw[100];
inline ll read()
{
	ll x = 0,f = 1;
	char ch;ch = getchar();
	while(ch < '0' || ch > '9')
	{
		if(ch == '-')  f = -1;
		ch = getchar();
	}
	while(ch >= '0' && ch <= '9')
	{
		x = (x<<1) + (x<<3) + ch^48;
		ch = getchar();
	}
	return x * f;
}
inline void write(ll x)
{
	if(x < 0)
	{
		x = -x;
		putchar('-');
	}
	if(x > 9)
	  write(x / 10);
	putchar(x%10+'0');
}
inline void push_up(ll p)
{
	t[p].val = t[p<<1].val + t[p<<1|1].val;
}
inline void push_down(ll l,ll r,ll p)
{
	ll mid = l + r >> 1;
	t[p<<1].tag += t[p].tag;
	t[p<<1|1].tag += t[p].tag;
	t[p<<1].val += (mid-l+1) * t[p].tag;
	t[p<<1|1].val += (r-mid) * t[p].tag;
	t[p].tag = 0;
}
inline void build(ll l,ll r,ll p)
{
	if(l == r)
	{
		t[p].val = a[l];
		return ;
	}
	ll mid = l + r >> 1;
	build(l,mid,p<<1);
	build(mid+1,r,p<<1|1);
	push_up(p);
}
inline void modify(ll n1,ll n2,ll l,ll r,ll p,ll k)
{
	if(n1 <= l && r <= n2)
	{
		t[p].tag += k;
		t[p].val += (r-l+1) * k;
		return ;
	}
	if(t[p].tag)  push_down(l,r,p);
	ll mid = l + r >> 1;
	if(n1 <= mid)  modify(n1,n2,l,mid,p<<1,k);
	if(n2 > mid)  modify(n1,n2,mid+1,r,p<<1|1,k);
	push_up(p);
}
inline ll query(ll n1,ll n2,ll l,ll r,ll p)
{
	if(n1 <= l && r <= n2)
	  return t[p].val;
	if(t[p].tag)  push_down(l,r,p);
	ll mid = l + r >> 1;
	ll res = 0;
	if(n1 <= mid)  res += query(n1,n2,l,mid,p<<1);
	if(n2 > mid)  res += query(n1,n2,mid+1,r,p<<1|1);
	return res;
}
inline void work()
{
	ll sum = query(1,n,1,n,1);
	ll ans = 0;
	ll w = W;
	for(int i = 0;i <= 40;i ++)
	{
		if(sum * pw[i] < w)
		{
			w -= sum * pw[i];
			ans += n;
		}
		else
		{
			ll l = 1,r = n;
			while(l <= r)
			{
				ll mid = l + (r-l)/2;
				ll res = query(1,mid,1,n,1);
				if(res * pw[i] >= w)
				  r = mid - 1;
				else
				  l = mid + 1;
			}
			ll cxk=0;
			if(query(1,l,1,n,1) * pw[i] < w)  cxk = max(cxk,l);
			if(query(1,r,1,n,1) * pw[i] < w)  cxk = max(cxk,r);
			ans += cxk;
			break;
		}
	}
	write(ans);
	printf("\n");
	
}
int main()
{
	n = read(),q = read(),W = read();
	for(int i = 1;i <= n;i ++)
	  a[i] = read();
	pw[0] = 1;
	for(int i = 1;i <= 40;i ++)
	  pw[i] = pw[i-1] * 2;
	build(1,n,1);
	while(q--)
	{
		ll l,r,d;
		l = read(),r = read(),d = read();
		modify(l,r,1,n,1,d);
		work();
	}
	return 0;
}
2024/10/23 21:40
加载中...