求助 WA 38pts
查看原帖
求助 WA 38pts
317805
BootsH楼主2023/8/17 17:18
#ifndef ONLINE_JUDGE
#define ONLINE_JUDGE
#endif

#include <fstream>
#include <iostream>

#include <algorithm>
#include <cassert>

namespace Solution
{
    #ifndef ONLINE_JUDGE
        std::ifstream cin("main.in");
        std::ofstream cout("main.out");
    #else
        using std::cin; 
        using std::cout;
    #endif
    
    #define int long long
    
    #define flp(name, lpst, lped) for (int name = lpst, name##end = lped; name <= name##end; ++name)
	#define plf(name, lpst, lped) for (int name = lpst, name##end = lped; name >= name##end; --name)
	
	using ll = long long;
	
	
	
	
	constexpr int maxn = 3e5 + 5;
	constexpr ll inf = 1e18;
	
	int n, q, m;
	
	struct Qry 
	{
		int op; ll s, k;
	} qry[maxn + maxn];
	
	ll ori[maxn + maxn], a[maxn + maxn + maxn], b[maxn + maxn + maxn];
	
	struct Node
	{
		ll sum0, sum, mx;
		int cnt, cnt0, tim, tag;
	} t[maxn << 3];
	
	void pup(int cur)
	{
		t[cur].sum = t[cur << 1].sum + t[cur << 1 | 1].sum;
		t[cur].cnt = t[cur << 1].cnt + t[cur << 1 | 1].cnt; 
	}
	
	int nowt = 1, ans;
	
	void pdn(int cur)
	{
		if (t[cur].tag == nowt)
		{
			t[cur << 1].tag = t[cur << 1 | 1].tag = nowt;
			t[cur << 1].tim = t[cur << 1 | 1].tim = nowt;
			t[cur << 1].sum = t[cur << 1 | 1].sum = t[cur << 1].cnt = t[cur << 1 | 1].cnt = 0;
		}
		t[cur].tag = 0;
		if (t[cur << 1].tim != nowt)
		{
			t[cur << 1].tim = nowt;
			t[cur << 1].sum = t[cur << 1].sum0, t[cur << 1].cnt = t[cur << 1].cnt0;
		}
		if (t[cur << 1 | 1].tim != nowt)
		{
			t[cur << 1 | 1].tim = nowt;
			t[cur << 1 | 1].sum = t[cur << 1 | 1].sum0, t[cur << 1 | 1].cnt = t[cur << 1 | 1].cnt0;
		}
	}
	
	ll calc(int L, int R, ll need, int l, int r, int cur)
	{
		if (t[cur].sum <= need)
		{
			ans += t[cur].cnt;
			t[cur].tag = nowt;
			ll tmp = t[cur].sum;
			t[cur].sum = t[cur].cnt = 0;
			return tmp;
		}
		if (l == r)
		{
			ll num = (need - 1) / b[l] + 1;
			ans += num;
			t[cur].cnt -= num, t[cur].sum -= b[l] * num;
			return b[l] * num;
		}
		pdn(cur);
		int mid = l + ((r - l) >> 1);
		ll res = 0;
		if (R <= mid)
		{
			res = calc(L, R, need, l, mid, cur << 1);
		}
		else if (L > mid)
		{
			res = calc(L, R, need, mid + 1, r, cur << 1 | 1);
		}
		else 
		{
			res = calc(mid + 1, R, need, mid + 1, r, cur << 1 | 1);
			if (res < need)
			{
				res += calc(L, mid, need - res, l, mid, cur << 1);
			}
		}
		pup(cur);
		return res;
	}
	
	void upd(int l, int r, int pos, int val, int cur)
	{
		t[cur].sum0 += val * b[pos], t[cur].cnt0 += val;
		if (l == r)
		{
			t[cur].mx = t[cur].cnt0 ? b[l] : 0;
			return ;
		}
		int mid = l + ((r - l) >> 1);
		if (pos <= mid)
		{
			upd(l, mid, pos, val, cur << 1);
		}
		else 
		{
			upd(mid + 1, r, pos, val, cur << 1 | 1);
		}
		t[cur].mx = std::max(t[cur << 1].mx, t[cur << 1 | 1].mx);
	}
	
	int getnxt(int l, int r, ll val, int cur)
	{
		if (t[cur].mx < val)
		{
			return 1e9; 
		}
		if (l == r)
		{
			return l;
		}
		int mid = l + ((r - l) >> 1);
		if (t[cur << 1].mx >= val)
		{
			return getnxt(l, mid, val, cur << 1);
		}
		return getnxt(mid + 1, r, val, cur << 1 | 1);
	}
	 

    void main(void)
    {
		std::ios::sync_with_stdio(false);
		cin.tie(nullptr), cout.tie(nullptr);   
		
		
		cin >> n;
		flp (i, 1, n)
		{
			cin >> ori[i];
			b[++m] = ori[i];
		}
		int q; cin >> q;
		flp (i, 1, q)
		{
			cin >> qry[i].op;
			if (qry[i].op == 1)
			{
				cin >> qry[i].s >> qry[i].k;
			}
			else 
			{
				cin >> qry[i].s;
				b[++m] = qry[i].s;
			}
		}
		std::sort(b + 1, b + m + 1);
		m = std::unique(b + 1, b + m + 1) - b - 1;
		flp (i, 1, n)
		{
			upd(1, m, std::lower_bound(b + 1, b + n + 1, ori[i]) - b, 1, 1);
		}
//		assert(q);
//		cout << "*****************\n";

		int flag = 1;
		
		flp (i, 1, q)
		{	
			flag &= (qry[i].op != 1);
			if (qry[i].op == 1)
			{
				ans = 0, ++nowt;
				t[1].cnt = t[1].cnt0, t[1].sum = t[1].sum0;
				ll now = qry[i].s;
				int k = getnxt(1, m, now, 1);
				while (now < qry[i].k && k > 1)
				{
					ll need = qry[i].k - now;
					if (k <= m)
					{
						need = std::min(need, b[k] - now + 1);
					}
					ll res = calc(1, k - 1, need, 1, m, 1);
					if (res < need)
					{
						break;
					}
					now += res;
					k = getnxt(1, m, now, 1);
				}
				if (now < qry[i].k)
				{
					cout << "-1\n";
				}
				else 
				{
					cout << ans << "\n";
				}
			}
			else if (qry[i].op == 2)
			{
				upd(1, m, std::lower_bound(b + 1, b + m + 1, qry[i].s) - b, 1, 1);
			}
			else if (qry[i].op == 3)
			{
				upd(1, m, std::lower_bound(b + 1, b + m + 1, qry[i].s) - b, -1, 1);
			}
		}
//		assert(!flag);
		
		     
    }
    
    #undef int
}

int main(void)
{
    Solution::main();
    return 0;
}
2023/8/17 17:18
加载中...