AT_abc342_g [ABC342G] Retroactive Range Chmax 题解

我会无脑做法,哈哈!

考虑没有删除操作怎么做?直接每个点维护一个标记,下传直接取 max\max 就好。

要删除,直接考虑线段树分治,删除变撤销。然而取 max\max 貌似不好直接撤销。考虑标记永久化,这样就不需要下传。单次区间修改影响 O(logn)O(\log n) 个节点,直接记录下来撤销即可。复杂度应该是 O(nlog2n)O(n \log^2 n) 的,然而我赛时实现套了个 map 变成了 O(nlog3n)O(n \log^3 n),仍然过了。

#include <bits/stdc++.h>
using namespace std;
//#define int long long

const int N = 2e5 + 5, MOD = 1e9 + 7, HSMOD = 1610612741, HSMOD2 = 998244353; // Remember to change

int n, m, q, t, a[N];
mt19937 rnd(chrono::system_clock::now().time_since_epoch().count());

long long qpow(long long a, long long b)
{
	long long res = 1ll, base = a;
	while (b)
	{
		if (b & 1ll) res = res * base % MOD;
		base = base * base % MOD;
		b >>= 1ll;
	}
	return res;
}

bool isprime(int x)
{
	if (x == 1) return 0;
	for (int i = 2; 1ll * i * i <= x; i++) if (x % i == 0) return 0;
	return 1;
}

namespace FastIo
{
	#define QUICKCIN ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
	int read()
	{
		char ch = getchar();
		int x = 0, f = 1;
		while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
		while (ch == '-')
		{
			f = -f;
			ch = getchar();
		}
		while (ch >= '0' && ch <= '9')
		{
			x = (x << 1) + (x << 3) + (ch ^ 48);
			ch = getchar();
		}
		return x * f;
	}
	template<class T>
	void write(T x)
	{
		if (x < 0)
		{
			putchar('-');
			x = -x;
		}
		if (x > 9) write(x / 10);
		putchar(x % 10 + '0');
	}
	template<class T>
	void writeln(T x)
	{
		write(x);
		putchar('\n');
	}
}

template<typename T>
class Bit
{
public:
	T lowbit(T x)
	{
		return x & -x;
	}
	T tr[N];
	void add(T x, T y)
	{
		while (x < N)
		{
			tr[x] += y;
			x += lowbit(x);
		}
	}
	T query(T x)
	{
		T sum = 0;
		while (x)
		{
			sum += tr[x];
			x -= lowbit(x);
		}
		return sum;
	}
};

map<int, int> vv;

class SegmentTree
{
public:
	struct Node
	{
		int l,r,tag;
	}tr[N<<2];
	void ptag(int u,int v)
	{
		if(!vv.count(u))vv[u]=tr[u].tag;
		tr[u].tag=max(tr[u].tag,v);
	}
	void build(int u,int l,int r)
	{
		tr[u]={l,r,0};
		if(l==r) return;
		int mid=l+r>>1;
		build(u<<1,l,mid);
		build(u<<1|1,mid+1,r);
	}
	void update(int u,int l,int r,int v)
	{
		if(tr[u].l>=l and tr[u].r<=r)
		{
			ptag(u,v);
			return;
		}
		int mid=tr[u].l+tr[u].r>>1;
		if(l<=mid) update(u<<1,l,r,v);
		if(r>mid) update(u<<1|1,l,r,v);
	}
	int query(int u,int x)
	{
		if(tr[u].l==tr[u].r) 
		{
			return max(a[tr[u].r],tr[u].tag);
		}
		int res=tr[u].tag;
		int mid=tr[u].l+tr[u].r>>1;
		if(x<=mid) res=max(res,query(u<<1,x));
		else res=max(res, query(u<<1|1,x));
		return res;
	}
}sgt;

struct Ope
{
	int l,r,v;
	Ope()=default;
	Ope(int l,int r,int v):l(l),r(r),v(v){}
};

Ope od[N];
int qr[N];

class Timesgt
{
public:
	struct Node
	{
		int l,r;
		vector<Ope> vec;
	}tr[N<<2];
	void build(int u,int l,int r)
	{
		tr[u]={l,r};
		tr[u].vec.clear();
		if(l==r) return;
		int mid=l+r>>1;
		build(u<<1,l,mid);
		build(u<<1|1,mid+1,r);
	}
	void update(int u,int l,int r,Ope& op)
	{
		if(tr[u].l>=l and tr[u].r<=r)
		{
			tr[u].vec.emplace_back(op);
			return;
		}
		int mid=tr[u].l+tr[u].r>>1;
		if(l<=mid) update(u<<1,l,r,op);
		if(r>mid) update(u<<1|1,l,r,op);
	}
	void solve(int u)
	{
		vv.clear();
		for(auto&[l,r,v]:tr[u].vec)
		{
			sgt.update(1,l,r,v);
		}
		if(tr[u].l==tr[u].r)
		{
			if(qr[tr[u].l])
			{
				cout<<sgt.query(1,qr[tr[u].l])<<"\n";
			}
			for(auto&[u,v]:vv) sgt.tr[u].tag=v;
			vv.clear();
			return;
		}
		vector<pair<int, int>> gg;
		for(auto&[uu,vg]:vv) gg.emplace_back(make_pair(uu,vg));
		vv.clear();
		solve(u<<1);
		solve(u<<1|1);
		for(auto&[uu,vg]:gg) 
		{
			sgt.tr[uu].tag=vg;
		}
	}
}s;

int ed[N];

int main()
{
	ios::sync_with_stdio(0), cin.tie(nullptr), cout.tie(nullptr);
	cin>>n;
	sgt.build(1,1,n);
	for(int i=1;i<=n;i++) cin>>a[i];
	cin>>m;
	s.build(1,1,m);
	for(int i=1;i<=m;i++)
	{
		int op;
		cin>>op;
		if(op==1)
		{
			cin>>od[i].l>>od[i].r>>od[i].v;
		}
		else if(op==2)
		{
			int x;
			cin>>x;
			//cout<<"!!!: " << x<<" "<<i-1<<"\n";
			s.update(1,x,i-1,od[x]);
			ed[x]=i;
		}
		else
		{
			int g;
			cin>>g;
			qr[i]=g;
		}
	}
	for(int i=1;i<=m;i++)
	{
		if(od[i].l&&!ed[i]) 
		{
			s.update(1,i,m,od[i]);
		}
	}
	s.solve(1);
	return 0;
}
posted @ 2024-02-25 09:00  HappyBobb  阅读(0)  评论(0编辑  收藏  举报  来源