• 欢迎光临~

luogu7476苦涩

开发技术 开发技术 2022-07-30 次浏览

「C.E.L.U-02」苦涩

题目背景

回想起自己的过往的人生,YQH 觉得心中充满了苦涩。如果人生能再来一次,我一定会少做一些傻事,少真香几次,然后大胆地去追寻自己的爱。可惜没有这样一个机会了。

题目描述

在 YQH 的梦中,他看到自己过去的记忆正在不断浮现在自己脑中。这些记忆带给他的是满满的苦涩。他想要强行忘记一些来减轻自己的苦涩。
YQH 的脑中可以被分成 (n) 个片区,每个片区相当于一个存放记忆的可重集,初始为空。他将进行 (m) 次这三种操作:
操作 1:区间 (lsim r) 的片区中都浮现了一个苦涩值为 (k) 的记忆。
操作 2:YQH 开始清理 (lsim r) 片区的记忆。如果一个片区 (kin[l,r])(k) 中苦涩值最大的记忆与 (lsim r) 片区中苦涩值最大的记忆相等,则将这个苦涩值最大的记忆忘记。如果在同一个片区有多个相同的苦涩值最大的记忆,则只忘记一个。如果这些片区内没有记忆,则无视。
操作 3:YQH 想知道,(lsim r) 片区中苦涩值最大的记忆的苦涩值是多少,如果不存在,输出-1

输入格式

第一行两个数,(n,m)
接下来 (m) 行,第一个数代表操作种类 (op),对于操作 1,有三个数 (l,r,k),对于操作 2 或 3,有两个数 (l,r)

输出格式

对于每个操作 3 输出一行,代表答案。

样例 #1

样例输入 #1

5 4
1 1 3 2
1 2 4 3
2 3 3
3 1 3

样例输出 #1

3

样例 #2

样例输入 #2

6 6
1 1 6 2
1 3 3 2
1 3 4 3
2 3 4
3 3 3
3 4 4

样例输出 #2

2
2

提示

样例解释

样例解释一

下面为各操作之后 YQH 的大脑的状态:
第一次操作:({2},{2},{2},varnothing,varnothing)
第二次操作:({2},{2,3},{2,3},{3},varnothing)
第三次操作:({2},{2,3},{2},{3},varnothing)
第四次操作询问 区间 (1sim 3) 的最大值,所以答案是 (3)

样例解释二

下面为各操作之后 YQH 的大脑的状态:
第一次操作:({2},{2},{2},{2},{2},{2})
第二次操作:({2},{2},{2,2},{2},{2},{2})
第三次操作:({2},{2},{2,2,3},{2,3},{2},{2})
第四次操作:({2},{2},{2,2},{2},{2},{2})
第五次操作询问 (3) 的最大值,所以答案是 (2)
第六次操作询问 (4) 的最大值,所以答案是 (2)

数据范围

Subtask n m 特殊性质
(1(10pts)) (leq10^3) (le10^3) (diagdown)
(2(20pts)) (leq5times10^4) (leq5times10^4) 没有操作 2
(3(10pts)) (leq5times10^4) (leq5times10^4) 操作 2 中 (l=r)
(4(20pts)) (leq5times10^4) (leq5times10^4) (diagdown)
(5(20pts)) (leq2times10^5) (leq2times10^5) 操作 2 中 (l=r)
(6(20pts)) (leq2times10^5) (leq2times10^5) (diagdown)

对于 (100%) 的数据,(n,mle2times10^5,kle10^9)


这个题目折腾了一天多!!!
明显是线段树,每个节点里面套一个堆!
刚开始想下传标记,想要下传中快速合并,就用左偏树呗!可是,写到合并了,发现当当前的的堆和左孩子合并后就没了,那谁和有孩子合并,又不能复制一个。后来一想,既然不能下传,干脆普通堆算了。可是还是下穿了一点东西,就是当堆顶的元素等于要清除的元素时,只能下传到包含的点再清楚。当然,这个只需要堆里面的插入删除就好了,logn!最后还错了一个更新点,调了一会儿就过了!


#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
int n,m;
struct node
{
	int mx;
	priority_queue<int>q;
}xds[maxn<<3];
void insert(int cur,int l,int r,int lq,int rq,int x)
{
	if(lq<=l&&r<=rq)
	{
		xds[cur].q.push(x);
		xds[cur].mx=max(xds[cur].mx,x);
		return;
	}
	int mid=(l+r)>>1;
	if(lq<=mid)insert(cur<<1,l,mid,lq,rq,x);
	if(mid<rq)insert(cur<<1|1,mid+1,r,lq,rq,x);
	xds[cur].mx=max(xds[cur].q.top(),max(xds[cur<<1].mx,xds[cur<<1|1].mx));
}
int query(int cur,int l,int r,int ql,int qr)
{
	if(ql<=l&&r<=qr)
	{
		return xds[cur].mx;
	}
	int mid=(l+r)>>1,ans=xds[cur].q.top();
	if(ql<=mid)ans=max(ans,query(cur<<1,l,mid,ql,qr));
	if(mid<qr)ans=max(ans,query(cur<<1|1,mid+1,r,ql,qr));
	return ans;
}
void down(int cur)
{
	int x=xds[cur].q.top();
	xds[cur].q.pop();
	xds[cur<<1].mx=max(xds[cur<<1].mx,x);
	xds[cur<<1|1].mx=max(xds[cur<<1|1].mx,x);
	xds[cur<<1].q.push(x);
	xds[cur<<1|1].q.push(x);
}
void clear(int cur,int l,int r,int ql,int qr,int x)
{
	if(l>r)return ;
	if(xds[cur].q.top()>x)return;
	if(xds[cur].mx<x)return;
	if(ql<=l&&r<=qr)
	{
		if(xds[cur].mx==x)
		{
			if(xds[cur].q.top()==x)
			{
				xds[cur].q.pop();
				xds[cur].mx=max(xds[cur].q.top(),max(xds[cur<<1].mx,xds[cur<<1|1].mx));
				return ;
			}
		}
	}
	int mid=(l+r)>>1;
	if(xds[cur].q.top()==x)down(cur);
	if(ql<=mid)clear(cur<<1,l,mid,ql,qr,x);
	if(mid<qr)clear(cur<<1|1,mid+1,r,ql,qr,x);
	xds[cur].mx=max(xds[cur].q.top(),max(xds[cur<<1].mx,xds[cur<<1|1].mx));
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=0;i<=(n<<3);++i)xds[i].mx=-1,xds[i].q.push(-1);
	while(m--)
	{
		int opt,l,r,x;
		scanf("%d%d%d",&opt,&l,&r);
		if(opt==1)
		{
			scanf("%d",&x);
			insert(1,1,n,l,r,x);
		}
		else if(opt==2)
		{
			int x=query(1,1,n,l,r);
			if(x!=-1)clear(1,1,n,l,r,x);
		}
		else
		{
			int mx=query(1,1,n,l,r);
			printf("%dn",mx);
		}
	}
	return 0;
	
}
程序员灯塔
转载请注明原文链接:luogu7476苦涩
喜欢 (0)