hdoj4027

本文介绍了一种使用线段树进行区间更新和查询的算法实现,具体为将区间内的每个数值替换为其平方根的向下取整值。通过递归方式更新线段树,并在查询操作中返回指定区间的总和。适用于数据规模不大于1e5的问题,能够有效处理区间修改和查询需求。
摘要由CSDN通过智能技术生成

线段树题目,区间修改,区间内每个数x->sqrt(x),向下取整,数据不是太大,n=1e5,2^63开根号最大也就8,9次,完全可以暴力,中间可以判断这个区间是否满足 贡献=长度,及sum=r-l+1的话,就不必修改这个区间了。(注意输出格式,还是x和y的大小关系,不一定x小于y的,得判断一下)
代码:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
#include <map>
using namespace std;
typedef long long ll;
typedef double db;
const int mod=1e9+7;
const int maxn=1e6+5;
const double eps=0.00000001;
struct D{
	int l,r;
	ll sum;
}tr[maxn*5];
ll a[maxn],v[maxn];
void build(int rt,int l,int r){
	tr[rt].l=l,tr[rt].r=r;
	if(l==r){
		tr[rt].sum=a[l];
		return;
	}
	int mid=(l+r)>>1;
	build(rt<<1,l,mid);
	build(rt<<1|1,mid+1,r);
	tr[rt].sum=tr[rt<<1].sum+tr[rt<<1|1].sum;
}
void update(int rt,int l,int r){
	if(tr[rt].l>=l&&tr[rt].r<=r&&tr[rt].r-tr[rt].l+1==tr[rt].sum) return;
	if(tr[rt].l==tr[rt].r){
		tr[rt].sum=sqrt(tr[rt].sum);
		return;
	}
	if(tr[rt<<1].l>r||tr[rt<<1|1].r<l) return;
	if(tr[rt<<1].r>=l) update(rt<<1,l,r);
	if(tr[rt<<1|1].l<=r) update(rt<<1|1,l,r);
	tr[rt].sum=tr[rt<<1].sum+tr[rt<<1|1].sum;
}
ll query(int rt,int l,int r){
	if(tr[rt].l>=l&&tr[rt].r<=r){
		return tr[rt].sum;
	}
	ll sum=0;
	if(tr[rt<<1].l>r||tr[rt<<1|1].r<l) return 0;
	if(tr[rt<<1].r>=l) sum+=query(rt<<1,l,r);
	if(tr[rt<<1|1].l<=r) sum+=query(rt<<1|1,l,r);
	return sum;
}
int main(){
	int n,c=0;
	while(scanf("%d",&n)!=EOF){
		int p=0;
		for(int i=1;i<=n;++i){
			scanf("%lld",&a[i]);
		}
		build(1,1,n);
		int m,s;
		scanf("%d",&m);
		while(m--){
			scanf("%d",&s);
			int x,y;
			scanf("%d%d",&x,&y);
			if(x>y) swap(x,y);
			if(s==1){
				v[++p]=query(1,x,y);
			}else{
				update(1,x,y);
			}
		}
		printf("Case #%d:\n",++c);
		for(int i=1;i<=p;++i) printf("%lld\n",v[i]);
		puts("");
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值