1. 程式人生 > >LOJ10128. 花神遊歷各國

LOJ10128. 花神遊歷各國

sqrt 標記 -c 程序 limits hide 請求 content 懶惰標記

花神喜歡步行遊歷各國,順便虐爆各地競賽。花神有一條遊覽路線,它是線型的,也就是說,所有遊歷國家呈一條線的形狀排列,花神對每個國家都有一個喜歡程度(當然花神並不一定喜歡所有國家)。

每一次旅行中,花神會選擇一條旅遊路線,它在那一串國家中是連續的一段,這次旅行帶來的開心值是這些國家的喜歡度的總和,當然花神對這些國家的喜歡程序並不是恒定的,有時會突然對某些國家產生反感,使他對這些國家的喜歡度 δ 變為 sqrt (δ)?(可能是花神虐爆了那些國家的 OI,從而感到乏味)。

現在給出花神每次的旅行路線,以及開心度的變化,請求出花神每次旅行的開心值。

輸入格式

第一行是一個整數 N,表示有 N 個國家;

第二行有 N 個空格隔開的整數,表示每個國家的初始喜歡度 δi?

第三行是一個整數 M,表示有 M 條信息要處理;

第四行到最後,每行三個整數 x,l,r,當 x=1 時詢問遊歷國家 lr 的開心值總和,也就是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

數據範圍與提示

對於全部數據,1n10^5,1m2×10^5,1lrn,0δi?10^9。

註:建議使用 sqrt 函數,且向下取整。

__________________________________________________________________________

懶惰標記為bool型,標記當前區域是否已經無需開方,也就是是否都是1或0.

bz[cur]=bz[cur<<1] && bz[cur<<1|1]

如果懶惰標記為1,則無需再做修改。

__________________________________________________________________________

技術分享圖片
 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 }
View Code

LOJ10128. 花神遊歷各國