uva11992 Fast Matrix Operations 线段树打标记

博主分享了自己首次尝试使用线段树lazy tag解决UVA11992问题的经历,题目涉及区间加、区间赋值、区间查询和维护区间和、最大值、最小值。由于题目限制,博主通过拆分为20个线段树来处理。在编程过程中遇到了全局变量初始化和runtime error的问题,最终经过调试实现了AC(Accepted)的代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       现在想起来自己好像从来都没有写过线段树lazy tag呢,唉真是惭愧。现在老师开始讲线段树了,我就被要求滚去写线段树啦。。

       这道题就是区间都加上一个值;区间都变为一个值;求区间和,最大值,最小值。其中行数<=20行,所以拆成20个线段树就好了。结果写了两h+(真是弱),然后全局变量pos在main()前面加了个int调了1h+,初始化还写炸了runtime error好几发。。好了不说了。

AC代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 500005
#define inf 1000000000
using namespace std;

int n,m,pos; struct node{ int x,y,z; };
int read(){
	int x=0; char ch=getchar();
	while (ch<'0' || ch>'9') ch=getchar();
	while (ch>='0' && ch<='9'){ x=x*10+ch-'0'; ch=getchar(); }
	return x;
}
struct sgtree{
	int c[N][2],val[N],add[N]; node p[N];
	void clear(){
		memset(val,-1,sizeof(val)); val[1]=0; int i;
		c[1][0]=1; c[1][1]=n;
		for (i=1; c[i][0]; i++){
			if (c[i][0]==c[i][1]) continue;
			int mid=(c[i][0]+c[i][1])>>1;
			c[i<<1][0]=c[i][0]; c[i<<1][1]=mid;
			c[(i<<1)|1][0]=mid+1; c[(i<<1)|1][1]=c[i][1];
		}
	}
	void pushup(int k){
		int ls=k<<1,rs=ls|1,len=c[k][1]-c[k][0]+1;
		if (len>1){
			p[k].x=min(p[ls].x,p[rs].x); p[k].y=max(p[ls].y,p[rs].y);
			p[k].z=p[ls].z+p[rs].z;
		}
		if (val[k]!=-1){ p[k].x=p[k].y=val[k]; p[k].z=val[k]*len; }
		p[k].x+=add[k]; p[k].y+=add[k]; p[k].z+=add[k]*len;
	}
	void pushdown(int k){
		int ls=k<<1,rs=ls|1;
		if (val[k]!=-1){
			val[ls]=val[rs]=val[k]; add[ls]=add[rs]=0; val[k]=-1;
		}
		add[ls]+=add[k]; add[rs]+=add[k]; add[k]=0;
	}
	void ins(int k,int u,int v,int num){
		int l=c[k][0],r=c[k][1],mid=(l+r)>>1;
		if (l==u && r==v){
			if (pos){ val[k]=num; add[k]=0; }else add[k]+=num;
			pushup(k); return;
		}
		pushdown(k);
		if (v<=mid){ ins(k<<1,u,v,num); pushup((k<<1)|1); }else
		if (u>mid){ ins((k<<1)|1,u,v,num); pushup(k<<1); }else{
			ins(k<<1,u,mid,num); ins((k<<1)|1,mid+1,v,num);
		}
		pushup(k);
	}
	node qry(int k,int u,int v,int now){		
		int l=c[k][0],r=c[k][1],mid=(l+r)>>1; node ans;
		if (val[k]!=-1){
			int tmp=val[k]+add[k]+now; ans.x=ans.y=tmp;
			ans.z=tmp*(v-u+1); return ans;
		}
		if (l==u && r==v){
			ans.x=p[k].x+now; ans.y=p[k].y+now;
			ans.z=p[k].z+now*(r-l+1); return ans;
		}
		if (v<=mid) return qry(k<<1,u,v,now+add[k]); else
		if (u>mid) return qry((k<<1)|1,u,v,now+add[k]); else{
			node t1=qry(k<<1,u,mid,now+add[k]),t2=qry((k<<1)|1,mid+1,v,now+add[k]);
			t1.x=min(t1.x,t2.x); t1.y=max(t1.y,t2.y); t1.z+=t2.z; return t1;
		}
	}
}a[21];
int main(){
	while (~scanf("%d%d",&m,&n)){
		int cas=read(),i;
		for (i=1; i<=m; i++) a[i].clear();
		while (cas--){
			pos=read(); int x1=read(),y1=read(),x2=read(),y2=read();
			if (pos<=2){
				pos--; int v=read(); for (i=x1; i<=x2; i++) a[i].ins(1,y1,y2,v);
			}else{
				node ans,t; ans.x=inf; ans.y=-inf; ans.z=0;
				for (i=x1; i<=x2; i++){
					t=a[i].qry(1,y1,y2,0); ans.z+=t.z;
					ans.x=min(ans.x,t.x); ans.y=max(ans.y,t.y);
				}
				printf("%d %d %d\n",ans.z,ans.x,ans.y);
			}
		}
	}
	return 0;
}

by lych

2015.12.19

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值