1. 程式人生 > >12:Challenge 5(線段樹區間直接修改)

12:Challenge 5(線段樹區間直接修改)

fin 所有 時間限制 hal 每一個 ++ ont bool nbsp

總時間限制:
10000ms
單個測試點時間限制:
1000ms
內存限制:
262144kB
描述

給一個長為N的數列,有M次操作,每次操作是以下兩種之一:

(1)將某連續一段同時改成一個數

(2)求數列中某連續一段的和

輸入
第一行兩個正整數N和M。
第二行N的整數表示這個數列。
接下來M行,每行開頭是一個字符,若該字符為‘M‘,則表示一個修改操作,接下來三個整數x、y和z,表示在[x,y]這段區間的數改為z;若該字符為‘Q‘,則表示一個詢問操作,接下來兩個整數x和y,表示求[x,y]這段區間的和。
輸出
對每一個詢問操作單獨輸出一行,表示答案。
樣例輸入
5 3
1 2 3 4 5
Q 1 5
M 2 3 2
Q 3 5
樣例輸出
15
11
提示
1<=N<=10^5,1<=M<=10^5,輸入保證合法,且所有整數及答案可用帶符號32位整型存儲。
對於線段樹的直接修改,
我們首先考慮要維護一個修改標記,
註意這個標記是可以每次被覆蓋的!
然後值直接區間修改就好
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #define ls k<<1
  5 #define rs k<<1|1
  6 using namespace std;
7 const int MAXN=100001; 8 const int maxn=0x7ffff; 9 void read(int &n) 10 { 11 char c=+;int x=0;bool flag=0; 12 while(c<0||c>9){c=getchar();if(c==-)flag=1;} 13 while(c>=0&&c<=9) 14 x=(x<<1)+(x<<3)+c-48,c=getchar(); 15 flag==1
?n=-x:n=x; 16 } 17 int n,m; 18 int ans=0; 19 struct node 20 { 21 int l,r,w,f; 22 node() 23 { 24 l=r=w=0; 25 f=-maxn; 26 } 27 }tree[MAXN<<2]; 28 void update(int k) 29 { 30 tree[k].w=tree[ls].w+tree[rs].w; 31 } 32 void build(int ll,int rr,int k) 33 { 34 tree[k].l=ll;tree[k].r=rr; 35 if(ll==rr) 36 { 37 read(tree[k].w); 38 return ; 39 } 40 int mid=(ll+rr)>>1; 41 build(ll,mid,ls); 42 build(mid+1,rr,rs); 43 update(k); 44 } 45 void push(int k) 46 { 47 tree[ls].w=(tree[ls].r-tree[ls].l+1)*tree[k].f; 48 tree[rs].w=(tree[rs].r-tree[rs].l+1)*tree[k].f; 49 tree[ls].f=tree[k].f; 50 tree[rs].f=tree[k].f; 51 tree[k].f=-maxn; 52 53 } 54 void change(int k,int wl,int wr,int v) 55 { 56 if(wr<tree[k].l||wl>tree[k].r) 57 return ; 58 if(wl<=tree[k].l&&tree[k].r<=wr) 59 { 60 tree[k].w=(tree[k].r-tree[k].l+1)*v; 61 tree[k].f=v; 62 return ; 63 } 64 int mid=(tree[k].l+tree[k].r)>>1; 65 if(tree[k].f!=-maxn) 66 push(k); 67 change(ls,wl,wr,v); 68 change(rs,wl,wr,v); 69 update(k); 70 } 71 void ask(int k,int wl,int wr) 72 { 73 if(wr<tree[k].l||wl>tree[k].r) 74 return ; 75 if(wl<=tree[k].l&&tree[k].r<=wr) 76 { 77 ans+=tree[k].w; 78 return ; 79 } 80 int mid=(tree[k].l+tree[k].r)>>1; 81 if(tree[k].f!=-maxn) 82 push(k); 83 ask(ls,wl,wr); 84 ask(rs,wl,wr); 85 update(k); 86 } 87 int main() 88 { 89 read(n);read(m); 90 build(1,n,1); 91 for(int i=1;i<=m;i++) 92 { 93 char c;int x,y; 94 cin>>c; 95 read(x);read(y); 96 if(c==M) 97 { 98 int v; 99 read(v); 100 change(1,x,y,v); 101 } 102 else 103 { 104 ans=0; 105 ask(1,x,y); 106 printf("%d\n",ans); 107 } 108 } 109 return 0; 110 } 111 12: Challenge 5最近的提交

12:Challenge 5(線段樹區間直接修改)