HDU4027 线段树修改

题意:区间开根+区间求和

思路:线段树比较基础题型,对于我这种新手很不错!

一开始有个想法,就用普通懒标记记录区间更改值,然而仔细想下,这样一定会更新到线段树的最底层,那么等于暴力,TLE无疑。

于是发现题目给了信息:每个数小于2^63,意味着每个数最多被开8次根

于是有两个想法

1.lazy标记记录开根次数,如果大于8直接返回;

2.当区间和==区间长度时(全为1时),直接返回;

我用了第二种方法,但是注意的是

1.题目中给的区间左右端点不一定是左小右大 2.每组数据输出结束后要空一行!

AC代码

/*
	最怕一生碌碌无为,还说平凡难能可贵。
*/
#include<bits/stdc++.h>
#define INF 100100
using namespace std;
struct data{
	long long sum,l,r;
}tr[INF*4];
long long l,r,m,n,c;
long long a[INF];
void update(long long k){
	tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
}
void build(long long k,long long s,long long t)
{
	tr[k].l=s;tr[k].r=t;
	if(s==t)
	{
		tr[k].sum=a[s];
		return;
	}
	long long mid=s+t>>1;
	build(k<<1,s,mid);
	build(k<<1|1,mid+1,t);
	update(k);
}
void modify(long long k,long long s,long long t)
{
	if(tr[k].l==tr[k].r)
	{
		tr[k].sum=(long long)sqrt((double)tr[k].sum); 
		return;
	}
	if(tr[k].sum==tr[k].r-tr[k].l+1&&s<=tr[k].l&&tr[k].r<=t)return;
	long long mid=tr[k].l+tr[k].r>>1;
	if(s<=mid)modify(k<<1,s,t);
	if(t>mid)modify(k<<1|1,s,t);
	update(k);
}
long long query(long long k,long long s,long long t)
{
	if(s<=tr[k].l&&tr[k].r<=t)return tr[k].sum;
	long long mid=tr[k].l+tr[k].r>>1;
	long long ans=0;
	if(s<=mid)ans+=query(k<<1,s,t);
	if(t>mid)ans+=query(k<<1|1,s,t);
	return ans;
}
int main()
{
	//freopen("in.in","r",stdin);
	//freopen("out1.txt","w",stdout);
	ios::sync_with_stdio(false);cin.tie(NULL);
	long long casee=0;
	long long t1,t2;
	while(cin>>n)
	{
		cout<<"Case #"<<++casee<<":"<<endl;
		for(long long i=1;i<=n;i++)
			cin>>a[i];
		build(1,1,n);
		cin>>m;
		while(m--)
		{
			cin>>c>>t1>>t2;
			l=min(t1,t2);
			r=max(t1,t2);
			if(c==0)
				modify(1,l,r);
			else cout<<query(1,l,r)<<endl;
		}
		cout<<endl;
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值