每一次旅行中,花神会选择一条旅游路线,它在那一串国家中是连续的一段,这次旅行带来的开心值是这些国家的喜欢度的总和,当然花神对这些国家的喜欢程序并不是恒定的,有时会突然对某些国家产生反感,使他对这些国家的喜欢度 δ 变为 √δ (可能是花神虐爆了那些国家的 OI,从而感到乏味)。 现在给出花神每次的旅行路线,以及开心度的变化,请求出花神每次旅行的开心值。
为了使时间复杂度降低,我们可以发现:
√1=1所以,最大数字109操作较少次数便能到1。所以在操作前判断一下,如果区间内都是1即可跳过。
#include<bits/stdc++.h>
#define ll long long
#define MAXNUM 1000000*4+10
using namespace std;
struct node{
ll l,r,lef,rig;
ll val,Max;
}tree[210000];
ll a[110000],len,n,m;
void build(ll l,ll r){
ll root=++len;
tree[root].l=l;tree[root].r=r;tree[root].lef=tree[root].rig=-1;
if(l==r)tree[root].val=tree[root].Max=a[l];
else{
ll mid=(l+r)/2;
ll lef=tree[root].lef=len+1;build(l,mid);
ll rig=tree[root].rig=len+1;build(mid+1,r);
tree[root].val=tree[lef].val+tree[rig].val;
tree[root].Max=max(tree[lef].Max,tree[rig].Max);
}
}
void update(ll root,ll l,ll r){
if(tree[root].Max<2) return ;
if(tree[root].l==tree[root].r){tree[root].val=sqrt(tree[root].val);tree[root].Max=tree[root].val;return ;}
ll lef=tree[root].lef,rig=tree[root].rig,mid=(tree[root].l+tree[root].r)/2;
if(r<=mid) update(lef,l,r);
else if(mid<l) update(rig,l,r);
else update(lef,l,mid),update(rig,mid+1,r);
tree[root].val=tree[lef].val+tree[rig].val;
tree[root].Max=max(tree[lef].Max,tree[rig].Max);
}
ll query(ll root,ll l,ll r){
if(tree[root].l>=l&&tree[root].r<=r) return tree[root].val;
ll lef=tree[root].lef,rig=tree[root].rig,mid=(tree[root].l+tree[root].r)/2;
if(r<=mid) return query(lef,l,r);
else if(mid<l) return query(rig,l,r);
else return query(lef,l,mid)+query(rig,mid+1,r);
}
int main(){
scanf("%lld",&n);
for(ll i=1;i<=n;i++) scanf("%lld",&a[i]);
build(1,n);
scanf("%lld",&m);
while(m--){
char s;cin>>s;
if(s=='2'){
ll x,y;scanf("%lld%lld",&x,&y);
update(1,x,y);
}else{
ll x,y;scanf("%lld%lld",&x,&y);
printf("%lld\n",query(1,x,y));
}
}
return 0;
}