LOJ10128. 花神游历各国
花神喜欢步行游历各国,顺便虐爆各地竞赛。花神有一条游览路线,它是线型的,也就是说,所有游历国家呈一条线的形状排列,花神对每个国家都有一个喜欢程度(当然花神并不一定喜欢所有国家)。
每一次旅行中,花神会选择一条旅游路线,它在那一串国家中是连续的一段,这次旅行带来的开心值是这些国家的喜欢度的总和,当然花神对这些国家的喜欢程序并不是恒定的,有时会突然对某些国家产生反感,使他对这些国家的喜欢度 δ 变为 sqrt (δ)
现在给出花神每次的旅行路线,以及开心度的变化,请求出花神每次旅行的开心值。
输入格式
第一行是一个整数 N,表示有 N 个国家;
第二行有 N 个空格隔开的整数,表示每个国家的初始喜欢度 δi;
第三行是一个整数 M,表示有 M 条信息要处理;
第四行到最后,每行三个整数 x,l,r,当 x=1 时询问游历国家 l 到 r 的开心值总和,也就是∑rδi ,当 x=2 时国家 l 到 r 中每个国家的喜欢度δi 变为sqrt(δi)
输出格式
每次 x=1 时,每行一个整数。表示这次旅行的开心度。
样例
样例输入
4
1 100 5 5
5
1 1 2
2 1 2
1 1 2
2 2 3
1 1 4
样例输出
101
11
11
数据范围与提示
对于全部数据,1≤n≤10^5,1≤m≤2×10^5,1≤l≤r≤n,0≤δi≤10^9。
注:建议使用 sqrt
函数,且向下取整。
__________________________________________________________________________
懒惰标记为bool型,标记当前区域是否已经无需开方,也就是是否都是1或0.
bz[cur]=bz[cur<<1] && bz[cur<<1|1]
如果懒惰标记为1,则无需再做修改。
__________________________________________________________________________
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e5+10; 4 typedef long long ll; 5 ll sum[maxn<<2],a[maxn]; 6 bool delt[maxn<<2]; 7 ll n,m; 8 void build(ll cur,ll l,ll r) 9 { 10 if(l==r) 11 { 12 sum[cur]=a[l]; 13 if(sum[cur]==0 || sum[cur]==1)delt[cur]=1; 14 return ; 15 } 16 ll mid=(l+r)>>1; 17 build(cur<<1,l,mid); 18 build(cur<<1|1,mid+1,r); 19 sum[cur]=sum[cur<<1]+sum[cur<<1|1]; 20 delt[cur]=delt[cur<<1] && delt[cur<<1|1]; 21 } 22 void change(ll cur,ll l,ll r,ll ql,ll qr) 23 { 24 if(delt[cur])return; 25 if(l==r) 26 { 27 sum[cur]=sqrt(sum[cur]); 28 if(sum[cur]==1 || sum[cur]==0)delt[cur]=1; 29 return ; 30 } 31 ll mid=(l+r)>>1; 32 if(ql<=mid)change(cur<<1,l,mid,ql,qr); 33 if(mid<qr)change(cur<<1|1,mid+1,r,ql,qr); 34 sum[cur]=sum[cur<<1]+sum[cur<<1|1]; 35 delt[cur]=delt[cur<<1] && delt[cur<<1|1]; 36 } 37 ll query(ll cur,ll l,ll r,ll ql,ll qr) 38 { 39 if(ql<=l && r<=qr)return sum[cur]; 40 ll ans=0,mid=(l+r)>>1; 41 if(ql<=mid)ans+=query(cur<<1,l,mid,ql,qr); 42 if(mid<qr)ans+=query(cur<<1|1,mid+1,r,ql,qr); 43 return ans; 44 } 45 int main() 46 { 47 scanf("%lld",&n); 48 for(int i=1;i<=n;++i)scanf("%lld",a+i); 49 build(1,1,n); 50 scanf("%lld",&m); 51 for(int op,ql,qr,i=0;i<m;++i) 52 { 53 scanf("%d%d%d",&op,&ql,&qr); 54 if(op==1)printf("%lld\n",query(1,1,n,ql,qr)); 55 else change(1,1,n,ql,qr); 56 } 57 return 0; 58 }