线段树HDU4027Can you answer these queries?

Posted 行码棋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树HDU4027Can you answer these queries?相关的知识,希望对你有一定的参考价值。

  • 博客主页: https://blog.csdn.net/qq_50285142
  • 欢迎点赞👍收藏✨关注❤留言 📝 如有错误,敬请指正
  • 🎈虽然生活很难,但我们也要一直走下去🎈

题目链接

一个序列,可以进行两种操作:1.对区间内的每个元素取平方根,取整数 2.询问区间的和

思路:
线段树乍一看是处理区间的问题,但是处理区间的问题求总和比较麻烦。
但是从取平方根入手,发现最大的 2 64 2^{64} 264取7次就会变成一,如果变成一的话,我们对变成一的区间进行特判(区间长度=区间和),就可以大大减少时间,那么就可以把区间修改化为单点修改。
而特判1的情况会避免TLE。

三大天坑:

  • 多组样例且有样例的描述Case
  • 每组样例后面有一个空行
  • 输入的区间可能是前大后小,需要进行转换
#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
const int dx[]={-1,0,1,0},dy[]={0,1,0,-1};
const int inf = 0x3f3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-6;
const int mod = 1e9+7;
const int N = 1e5+5,M = 2e5+5;

int n,m,k;
ll a[N];

struct node
{
	int l,r;
	ll sum ;
}tr[N*4];

void pushup(int u)
{
	tr[u].sum = tr[u<<1].sum + tr[u<<1|1].sum;
}
void build(int u,int l,int r)
{
	tr[u] = {l,r};
	if(l==r) 
	{
		tr[u].sum = a[l];
		return ;
	}
	int mid = tr[u].l + tr[u].r >> 1;
	build(u<<1,l,mid);
	build(u<<1|1,mid+1,r);
	pushup(u);
}

void modify(int u,int l,int r)
{
	if(tr[u].sum == tr[u].r-tr[u].l+1 && tr[u].l>=l && tr[u].r <= r) 
		return;
	if(tr[u].l == tr[u].r)
	{
		tr[u].sum = sqrt(tr[u].sum);
		return;
	}
	int mid = tr[u].l + tr[u].r >> 1;
	if(l <= mid) modify(u<<1,l,r);
	if(r > mid) modify(u<<1|1,l,r);
	pushup(u);
}

ll query(int u,int l,int r)
{
	if(tr[u].l >= l && tr[u].r <= r) return tr[u].sum;
	int mid = tr[u].l + tr[u].r >> 1;
	ll res = 0;
	if(l <= mid) res += query(u<<1,l,r);
	if(r > mid) res += query(u<<1|1,l,r);
	return res; 
}
void solve()
{
	int _ = 0;
	while(~scanf("%d",&n))
	{
		printf("Case #%d:\\n",++_);
		for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
		build(1,1,n);
		scanf("%d",&m);
		while(m--)
		{
			int t,x,y;
			scanf("%d %d %d",&t,&x,&y);
			if(x>y) swap(x,y);
			if(t) printf("%lld\\n",query(1,x,y));
			else modify(1,x,y);
		}
		printf("\\n");
	} 
}
int main()
{
//	ios::sync_with_stdio(false);
//	cin.tie(0),cout.tie(0);
	int _;
//	cin>>_;
	_ = 1;
	while(_--)
	{
		solve();
	}
	return 0;
}


往期优质文章推荐

如果我的文章对你有帮助,欢迎点赞+评论+关注

欢迎微信搜索『行码棋』同名公众号,点击『获取资源』领取大量资源哦。

以上是关于线段树HDU4027Can you answer these queries?的主要内容,如果未能解决你的问题,请参考以下文章

HDU 4027 Can you answer these queries?(线段树)

HDU-4027 Can you answer these queries?(线段树区间开方)

HDU - 4027 Can you answer these queries? (线段树)

HDU 4027 Can you answer these queries?(线段树区间开方)

HDU-4027 Can you answer these queries? --线段树

HDU 4027 Can you answer these queries?(线段树/区间不等更新)