P1503 鬼子进村 题解

分析

分块。

我们定义 cnti 表示房子 i 是否出现过,sumi 表示在第 i 个块内没有被摧毁的房子数量,维护的房子是 (i1)×S1i×S,其中 S=n 也就是块长。

操作 1。写一个栈,根据后进先出的特点,讲摧毁的房子 x 入栈,以便后面修复。将 cntxx 对应块的 sum1 即可。

操作 2。先从栈里找到被修复的房子 x。与操作 1 同理,将减 1 变成加 1 即可。

操作 3。对于 x 能走到的房子,一定是在 [l,r] 满足 i=lrcnti=(rl+1) 的情况下的最大区间。我们可以分开来求。对于暴力,我们从 x 开始一直走,直到某一个 cnti=0 为止,能证明这是最大区间的 lr 同理,不在此赘述。考虑优化,我们可以先找到 x 所在的块 kx,暴力求 kx 中的贡献,再对于整块求贡献,最后对于不完整的块(答案边界)暴力。这里需要特别对 kx=kn 进行判断,因为 kn×S 可能大于 n,即最后一个块不完整。这时候直接暴力。由于我们是分开求 l,r 两边的贡献的,这时候在 cntx=1 的情况会将 x 的贡献重复加 1 遍,所以要对贡献和减 1

复杂度是 O(nn) 的。

代码

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

const int N=5e4+10;
int cnt[N],sum[N],block,len;
int n,m;
int st[N],tt;

il int get(int x){return (x-1)/len+1;}
il int findl(int x){
	block=get(x);
	int ans=0;
	for(re int i=x;i>=((block-1)*len)+1;--i)
		if(!cnt[i]) return ans;
		else ans++;
	--block;
	for(;block>=1;--block)
		if(sum[block]==len) ans+=len;
		else for(re int i=block*len;i>=((block-1)*len)+1;--i)
			if(!cnt[i]) return ans;
			else ans++;
	return ans;
}
il int findr(int x){
	int maxx=get(n);
	block=get(x);
	int ans=0;
	for(re int i=x;i<=block*len&&i<=n;++i)
		if(!cnt[i]) return ans;
		else ans++;
	++block;
	for(;block<maxx;++block)
		if(sum[block]==len) ans+=len;
		else for(re int i=(block-1)*len+1;i<=block*len;++i)
			if(!cnt[i]) return ans;
			else ans++;
	for(re int i=(block-1)*len+1;i<=n;++i)
		if(!cnt[i]) return ans;
		else ans++;
	return ans;
}

il void solve(){
	cin>>n>>m;len=sqrt(n);
	for(re int i=1;i<=n;++i) ++cnt[i],++sum[get(i)];
	for(re int i=1;i<=m;++i){
		char op;int x,now;cin>>op;
		if(op=='D') cin>>x,st[++tt]=x,--cnt[x],--sum[get(x)];
		else if(op=='R') now=st[tt--],++cnt[now],++sum[get(now)];
		else cin>>x,cout<<((!cnt[x])?0:findl(x)+findr(x)-1)<<"\n";
	}
	return ;
}

signed main(){
	solve();
	return 0;
}
posted @   harmis_yz  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示