首页 > 其他分享 >题解:【TJOI2012】防御

题解:【TJOI2012】防御

时间:2022-08-24 18:15:20浏览次数:85  
标签:read 题解 TJOI2012 int tag 防御 INF define

【TJOI2012】防御

题目链接

小清新数据结构题,题解区为啥清一色两棵线段树。

考虑分块,维护两个数组:$tag$ 和 $minx$ 分别记录整块的累计伤害和当前护盾最小值。当发现有护盾值为负数时,将它赋值为 $INF$,然后暴力重新扫块内并下放 $tag$,对于盾值为 $INF$ 的累加 $tag \times 2$,否则就累加 $tag$ 即可。

对于一个点最多重扫一次,重扫一次复杂度为 $O(\sqrt N)$ ,总复杂度为 $O(N \sqrt N)$,事实上因为一次块内重扫可能将多个盾值标记为 $INF$,所以实际跑起来一般达不到上界。

需要注意的地方是对盾值做减法的时候要先判断当前盾值与 $tag$ 的关系,如果已经爆盾了只不过伤害还寄存在 $tag$ 里,就应该先下放 $tag$。

跑的比某些线段树还要快吗?

$Code$

#include<bits/stdc++.h>
#define int long long
#define MAX 100010
#define INF 999999999
#define mod 1000000009
using namespace std;

inline int read()
{
	int s=0;
	char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) s=(s<<1)+(s<<3)+(c^48),c=getchar();
	return s;
}

int n,m;
char op;
int blo,bn;
int a[MAX],l[MAX],r[MAX],pos[MAX],tag[MAX],minx[MAX];

inline void block()
{
	n=read(),m=read();
	memset(minx,0x3f,sizeof minx);
	for(int i=1;i<=n;i++)
	{
		a[i]=read();
		if(a[i]==0) a[i]=INF;
	}
	blo=sqrt(n);bn=(n-1)/blo+1;
	for(int i=1;i<=bn;i++)
		l[i]=(i-1)*blo+1,r[i]=i*blo;
	r[bn]=n;
	for(int i=1;i<=bn;i++)
		for(int j=l[i];j<=r[i];j++)
			pos[j]=i,minx[i]=min(minx[i],a[j]);
	return;
}

int ans[MAX];
inline void spread(int x)
{
	minx[x]=INF;
	for(int i=l[x];i<=r[x];i++)
	{
		if(a[i]==INF) ans[i]+=2*tag[x];
		else ans[i]+=tag[x],a[i]-=tag[x];
		if(a[i]<=0) a[i]=INF;
		minx[x]=min(minx[x],a[i]);
	}
	tag[x]=0;
	return;
}
inline void change(int L,int R,int k)
{
	int p=pos[L],q=pos[R];
	if(p==q)
	{
		if(minx[p]<=tag[p]+k) spread(p);   //先判断是否需要下放!!!
		for(int i=L;i<=R;i++)
		{
			if(a[i]==INF) ans[i]+=2*k;
			else a[i]-=k,ans[i]+=k;	
			minx[p]=min(minx[p],a[i]);			
			if(a[i]<=0) a[i]=INF;
		}
		if(minx[p]<=tag[p]) spread(p);
	}
	else
	{
		for(int i=p+1;i<=q-1;i++)
		{
			if(minx[i]<=tag[i]+k) spread(i);
			tag[i]+=k;
		}
		if(minx[p]<=tag[p]+k) spread(p);
		for(int i=L;i<=r[p];i++)
		{
			if(a[i]==INF) ans[i]+=2*k;
			else a[i]-=k,ans[i]+=k;
			minx[p]=min(minx[p],a[i]);
			if(a[i]<=0) a[i]=INF;
		}
		if(minx[p]<=tag[p]) spread(p);
		if(minx[q]<=tag[q]+k) spread(q);
		for(int i=l[q];i<=R;i++)
		{
			if(a[i]==INF) ans[i]+=2*k;
			else a[i]-=k,ans[i]+=k;
			minx[q]=min(minx[q],a[i]);
			if(a[i]<=0) a[i]=INF;
		}
		if(minx[q]<=tag[q]) spread(q);
	}
	return;
}
inline int getsum(int x)
{
	int p=pos[x];
	if(a[x]==INF) return ans[x]+2*tag[p];
	return ans[x]+tag[p];
}

int x,y,k;
int answer;
inline void work()
{
	for(int i=1;i<=m;i++)
	{
		cin>>op;
		switch(op)
		{
			case 'A':x=read(),y=read(),k=read();change(x,y,k);break;
			case 'Q':x=read();answer+=getsum(x);break;
		}
	}
	cout<<answer%mod;
	return;
}

signed main()
{
	block();
	work();
	return (0-0);
}

标签:read,题解,TJOI2012,int,tag,防御,INF,define
From: https://www.cnblogs.com/LittleTwoawa/p/16621109.html

相关文章

  • 题解:【THUSCH2017】 大魔法师
    【THUSCH2017】大魔法师题目链接前言线段树和矩阵乘法的板子拼接题,这个题题目本身思维难度不大,但是可以给我们提供许多平时写代码的底层优化技巧。题目思路首先回到......
  • 题解:【POI2001】Goldmine
    【POI2001】Goldmine题目链接扫描线板子题,本质上这个题跟窗口的星星是一样的,只不过把权值$k$都换成$1$就行。但是需要注意的是这句话:(若矿石位于这块地的边缘,我们同......
  • 数的划分 题解
    \(0.\)写在前面1.3【例题1】数的划分-TuringEDUP2706数的划分-TopsCoding这题可以有两种写法:(至少两种)深搜计数\(\text{DP}\)接下来将会依次讲解\(1.\)......
  • 题解:【WC2005】双面棋盘
    【WC2005】双面棋盘题目链接这天做双面棋盘这道题,发现题解里面大多都是LCT,对于线段树套并查集的写法思路讲评很少而且不大清晰,因此有了这一篇题解。维护联通块的数量,......
  • has been blocked by CORS policy跨域问题解决
    title:hasbeenblockedbyCORSpolicy跨域问题解决我们在前端调用接口时,浏览器有时候会报错:XXXXformXXXXXhasbeenblockedbyCORSpolicy:No'Access-Control-......
  • CF1715F Crop Squares 题解
    CF1715FCropSquaressolution有一个\(n\timesm\)的长方形,四个角的坐标分别为$(0,0)$,$(0,m)$,$(n,0)$,$(n,m)$。在长方形里面有一个\(1\time......
  • CF838D题解
    很厉害的题。考虑将原本的座位串成一个环,然后加一个节点在\(1\)的前面\(n\)的后面。原问题等价为新节点不被座到的方案数。容易发现所有节点被座到和不被座到的方案......
  • 关于npm ERR! ERESOLVE could not resolve 问题解决
    1、问题描述从代码仓库拉取代码到本地,执行npminstall命令安装项目依赖,提示如下图错误  问题出现的原因由于npm版本问题,npm不同版本库之间命令不兼容。解决办法:执......
  • App 自动化测试实战技巧与经典面试题解析
    ⬇️点击“下方链接”,提升测试核心竞争力!>>更多技术文章分享和免费资料领取移动互联网时代,为了高效应对App多端发布、多版本发布、多机型发布等质量挑战,App自动化测试......
  • [题解]轮流拿牌问题_一道博弈论笔试题(C++)
    题目A和B轮流从一个数组左右两端取数,A先B后,每次取一个数,最终取数总和大者获胜,两人每次都会选择最有利的策略,求获胜者取数的和。思路笔试时遇到的一道算法题,也是博弈论中......