The Child and Sequence
生活随笔
收集整理的這篇文章主要介紹了
The Child and Sequence
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Codeforces Round #250 (Div. 1)D:http://codeforces.com/problemset/problem/438/D
題意:給你一個序列,然后有3種操作 1x y.表示查詢[x,y]之間的區間和,2 x y z表示把[x y]內的數%z,3x y,表示把第x個數變成y。
題解:肯定是用線段樹來維護,但是一開始想不到維護什么統計量,對于區間取模,沒辦法用lazy標記,更新到第的話,肯定會T。后來,認為既然沒辦法用lazy,那么只能用別的方法來優化更新。發現每次取模之后,數都會變小,如果要取模的數比當前模數小的話,就不用取模,于是可以維護區間最大值,如果區間最大值都小于模數的話,這個區間肯定不用更新,這樣來減少更新。這樣的方法,其實以前也做過,就是對于一個區間內的數進行開平方操作,每個數會越開越小,到了1的時候就可以直接不開了。因此,對于線段樹的區間更新來說:1如果能找到好的lazy可以標記的話,就使用lazy標記;2如果找不到就要想辦法優化區間更新,讓單點更新的次數變少。另外此題,自己用線段樹省空間的寫法,結果不熟練,一個地方寫錯,最后wa幾發。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 const int N=1e5+19; 7 int n,m; 8 long long sum[N*4],maxn[N*4]; 9 void pushup(int rt){ 10 sum[rt]=sum[rt<<1]+sum[rt<<1|1]; 11 maxn[rt]=max(maxn[rt<<1],maxn[rt<<1|1]); 12 } 13 void build(int l,int r,int rt){ 14 if(l==r){ 15 scanf("%I64d",&maxn[rt]); 16 sum[rt]=maxn[rt]; 17 return; 18 } 19 int mid=(l+r)/2; 20 build(l,mid,rt<<1); 21 build(mid+1,r,rt<<1|1); 22 pushup(rt); 23 } 24 void update(int l,int r,int rt,int from,int to,long long mod){ 25 if(maxn[rt]<mod)return; 26 if(l==r){ 27 maxn[rt]%=mod; 28 sum[rt]=maxn[rt]; 29 return; 30 } 31 int mid=(l+r)/2; 32 if(mid>=to)update(l,mid,rt<<1,from,to,mod); 33 else if(mid<from)update(mid+1,r,rt<<1|1,from,to,mod); 34 else{ 35 update(l,mid,rt<<1,from,mid,mod); 36 update(mid+1,r,rt<<1|1,mid+1,to,mod); 37 } 38 pushup(rt); 39 } 40 void update2(int l,int r,int rt,int pos,long long val){ 41 if(l==r){ 42 maxn[rt]=val; 43 sum[rt]=val; 44 return; 45 } 46 int mid=(l+r)/2; 47 if(mid>=pos)update2(l,mid,rt<<1,pos,val); 48 else update2(mid+1,r,rt<<1|1,pos,val); 49 pushup(rt); 50 } 51 long long query(int l,int r,int rt,int from,int to){ 52 if(l==from&&r==to){ 53 return sum[rt]; 54 } 55 int mid=(l+r)/2; 56 if(mid>=to)return query(l,mid,rt<<1,from,to); 57 else if(mid<from)return query(mid+1,r,rt<<1|1,from,to); 58 else { 59 return query(l,mid,rt<<1,from,mid)+query(mid+1,r,rt<<1|1,mid+1,to); 60 61 } 62 } 63 int t,t1,t4; 64 long long t2,t3; 65 int main(){ 66 while(~scanf("%d%d",&n,&m)){ 67 memset(sum,0,sizeof(sum)); 68 memset(maxn,0,sizeof(maxn)); 69 build(1,n,1); 70 for(int i=1;i<=m;i++){ 71 scanf("%d%d",&t,&t1); 72 if(t==1){ 73 scanf("%d",&t4); 74 printf("%I64d\n",query(1,n,1,t1,t4)); 75 } 76 else if(t==2){ 77 scanf("%d%I64d",&t4,&t2); 78 update(1,n,1,t1,t4,t2); 79 } 80 else{ 81 scanf("%I64d",&t2); 82 update2(1,n,1,t1,t2); 83 } 84 } 85 } 86 } View Code?
轉載于:https://www.cnblogs.com/chujian123/p/3870081.html
總結
以上是生活随笔為你收集整理的The Child and Sequence的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android node
- 下一篇: QtCreator无法编辑源文件