线段树上二分wa on 16 19 20
查看原帖
线段树上二分wa on 16 19 20
776232
zhizhizhiwang楼主2024/10/25 23:17

第一次写树上二分(

#include <iostream>
#include <algorithm>
#include <cstring>
#include <stdint.h>


using namespace std;

int64_t read_idx = 0;

template<typename T>
void read(T &x)
{
    x = 0;
	int f = 1;
    char ch = getchar();
    while(!isdigit(ch))
    {
        if(ch == '-') f = -f;
        ch = getchar();
    }
    while(isdigit(ch))
    {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    
    x *= f;
    return ;
}

template <typename T, typename... Args>
void read(T &x, Args & ... args)
{
    read<T>(x);
    read(args...);
}

template <typename T>
void print(const T x)
{
    int t = x;
    if(x < 0) t = -x;
    if(x > 9) print(t / 10);
    putchar((t % 10) + '0');
}

void print(const char* ch)
{
    size_t l = strlen(ch);
    for(size_t i = 0;i < l;i++)
        putchar(ch[i]);
}

template <typename T, typename... Args> 
void print(T x, Args... args)
{
    print(x);
    print(args...);
}

namespace local
{
	const int N = 2e5 + 10;
	
	
	int32_t w[N];	
    int64_t q, n, W;
	
	struct Node;
	extern Node tree[];
	
	struct Node
	{
		int32_t 		l, r;
		int64_t 		num;
		int64_t 		add;
		int32_t 		n;
		inline Node& 		left() {return tree[n << 1];}
		inline int32_t 		left_idx() {return n << 1;}
		inline Node&		right() {return tree[n << 1 | 1];}
		inline int32_t 		right_idx() {return n << 1 | 1;}	
		
		Node()
		{
			l = r = num = add = 0;
		}
	};
	
	
	Node tree[4 * N];
	
	inline void tree_init()
	{
		tree[1].n = 1;
		return ;
	}
	
	inline void push_up(Node &n)
	{
		n.num = n.left().num + n.right().num;
		return ;
	}
	
	inline void build(Node &n, int32_t l, int32_t r)
	{
		if(l == r)
		{
			n.l = l;
			n.r = r;
			n.num = w[l];
			n.add = 0;
		}
		else
		{
			n.l = l;
			n.r = r;
			n.left().n = n.left_idx();
			n.right().n = n.right_idx();
			int64_t mid = r + ((l - r) >> 1);
			build(n.left(), l, mid);
			build(n.right(), mid + 1, r);
			push_up(n);
		}
		return ;
	}
	

	
	inline void eval(Node &n, int32_t add)
	{
// 		printf("n.n : %lld n.l: %lld n.r : %lld\n", n.n, n.l, n.r);
		n.num += (n.r - n.l + 1) * add;
		n.add += add;
		return ;
	}
	
	inline void eval(Node &n, Node &fa)
	{
//		printf("n.n : %lld l: %lld r : %lld\n", n.n, n.l, n.r);
		return eval(n, fa.add);
	}	


	inline void push_down(Node &n)
	{
		eval(n.left() , n);
		eval(n.right(), n);
		n.add = 0;
		return ;
	}
	

	inline void modify(Node &n, int32_t l, int32_t r,int32_t add )
	{	
		if(n.l >= l and n.r <= r) eval(n, add);
		else
		{
			push_down(n);
			int64_t mid = n.l + ((n.r - n.l) >> 1);
			if(l <= mid) modify(n.left() , l, r, add);
			if(r > mid)  modify(n.right(), l, r, add);
			push_up(n);
		}
		return ;
	}
	

	inline int64_t query(Node &u, int32_t l, int32_t r)
	{
		if(u.l >= l and u.r <= r) return u.num;
		
		int64_t mid = u.l + ((u.r - u.l) >> 1);
		int64_t sum = 0;
		
		push_down(u);
		if(l <= mid) sum += query(u.left() , l, r);
		if(r > mid)  sum += query(u.right(), l, r);
		return sum;
	}
	

	inline int64_t find(Node &u, int64_t k, int64_t mul)
	{
		if(u.l == u.r) return u.l;
		push_down(u);
		int64_t now = u.left().num * mul;
		if(now <= k)
		{
			return find(u.right(), k - now, mul);
		}else{
			return find(u.left() , k, mul);
		}
	}

	inline int64_t check()
	{
		int64_t ans = 0;
		int64_t health = W;
		int64_t mul = 1;
		int64_t sum = query(tree[1], 1, n);

		for(;health > sum * mul;mul *= 2)
		{
			health -= sum * mul;
			ans += n;
		}
		/*
		while(r - l > 1)
		{
			mid = l + ((r - l) >> 1);
            now = query(tree[1], 1, mid) * mul;
			if(now == health)
			{
				r = mid;
				break;
			}
			else if(now > health)
			{
				r = mid;
			}
			else
			{
				l = mid;
			}
		}
		*/

		int64_t mid = find(tree[1], health, mul);
		if(query(tree[1], 1, mid) * mul >= health) mid--;
		ans += mid;
		return ans;
	}
}


int main()
{

//	freopen("C:\\Users\\xpwan\\Desktop\\c++\\p11217\\wxyt3.in", "r", stdin);
//	freopen("C:\\Users\\xpwan\\Desktop\\c++\\wxyt3.out", "w", stdout);

	using namespace local;
	
	read(n, q, W);	

	for(int i = 1;i <= n;i++)
	{
		read(w[i]);
	}
	
	tree_init();
	build(tree[1], 1, n);
	
	for(int l, r, d, i = 1;i <= q;i ++)
	{
		read(l, r, d);
		modify(tree[1], l, r, d);
		printf("%lld\n",check());
	}
	
}
2024/10/25 23:17
加载中...