线段树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?(线段树区间开方)