线段树
这是一道线段树的裸题……带单点修改的RMQ
为什么我会想到写这么一道傻逼题呢?是因为这样……
我很好奇那个突然冒出来的黄色箭头是什么……所以就去切了一下这道水题……
毫无压力地快速敲完……突然萌生了一种想法:试试自底向上线段树!
重新看了下zkw大牛的《统计的力量》,发现确实好写,而且灰常好用!
写的时候出现的问题:读入应该是读到[n+1,n+n]这一段,而我读到了[n+i-1,n+n-1]……(也就是说:1~n格是树中节点,后n个格是叶子节点)
1 int t[N<<2],a[N]; 2 #define L (o<<1) 3 #define R (o<<1|1) 4 #define mid (l+r>>1) 5 void maintain(int o,int l,int r){ 6 if (l<r) t[o]=max(t[L],t[R]); 7 } 8 void build(int o,int l,int r){ 9 if (l==r) t[o]=a[l]; 10 else{ 11 build(L,l,mid); 12 build(R,mid+1,r); 13 maintain(o,l,r); 14 } 15 } 16 void update(int o,int l,int r,int pos,int v){ 17 if (l==r) t[o]=v; 18 else{ 19 if (pos<=mid) update(L,l,mid,pos,v); 20 else update(R,mid+1,r,pos,v); 21 maintain(o,l,r); 22 } 23 } 24 int ql,qr,ans; 25 void query(int o,int l,int r){ 26 if (ql<=l && qr>=r) ans=max(ans,t[o]); 27 else{ 28 if (ql<=mid) query(L,l,mid); 29 if (qr>mid) query(R,mid+1,r); 30 } 31 }
普通线段树
1 int t[N<<2],n,m; 2 void update(int p,int v){ 3 for(t[p+=n]=v,p>>=1;p;p>>=1) 4 t[p]=max(t[p+p],t[p+p^1]); 5 } 6 int ans; 7 void query(int l,int r){ 8 for(l=l+n-1,r=r+n+1;l^r^1;l>>=1,r>>=1){ 9 if (!(l&1)) ans=max(t[l^1],ans); 10 if ( r&1) ans=max(t[r^1],ans); 11 } 12 }
zkw线段树
完整代码:(确实快了好多!而且代码短了好多……)
1 //HDOJ 1754 2 #include<cmath> 3 #include<vector> 4 #include<cstdio> 5 #include<cstring> 6 #include<cstdlib> 7 #include<iostream> 8 #include<algorithm> 9 #define rep(i,n) for(int i=0;i<n;++i) 10 #define F(i,j,n) for(int i=j;i<=n;++i) 11 #define D(i,j,n) for(int i=j;i>=n;--i) 12 #define pb push_back 13 #define CC(a,b) memset(a,b,sizeof(a)) 14 using namespace std; 15 int getint(){ 16 int v=0,sign=1; char ch=getchar(); 17 while(!isdigit(ch)) {if(ch==‘-‘) sign=-1; ch=getchar();} 18 while(isdigit(ch)) {v=v*10+ch-‘0‘; ch=getchar();} 19 return v*sign; 20 } 21 const int N=200010,INF=~0u>>2; 22 const double eps=1e-8; 23 /*******************template********************/ 24 25 int t[N<<2],a[N],cnt; 26 #define L (o<<1) 27 #define R (o<<1|1) 28 #define mid (l+r>>1) 29 void maintain(int o,int l,int r){ 30 if (l<r) t[o]=max(t[L],t[R]); 31 } 32 33 void build(int o,int l,int r){ 34 if (l==r) t[o]=a[l]; 35 else{ 36 build(L,l,mid); 37 build(R,mid+1,r); 38 maintain(o,l,r); 39 } 40 } 41 void update(int o,int l,int r,int pos,int v){ 42 if (l==r) t[o]=v; 43 else{ 44 if (pos<=mid) update(L,l,mid,pos,v); 45 else update(R,mid+1,r,pos,v); 46 maintain(o,l,r); 47 } 48 } 49 int ql,qr,ans; 50 void query(int o,int l,int r){ 51 if (ql<=l && qr>=r) ans=max(ans,t[o]); 52 else{ 53 if (ql<=mid) query(L,l,mid); 54 if (qr>mid) query(R,mid+1,r); 55 } 56 } 57 int main(){ 58 #ifndef ONLINE_JUDGE 59 freopen("input.txt","r",stdin); 60 // freopen("output.txt","w",stdout); 61 #endif 62 int n,m; 63 while(scanf("%d%d",&n,&m)!=EOF){ 64 F(i,1,n) a[i]=getint(); 65 build(1,1,n); 66 char s[4]; 67 F(i,1,m){ 68 scanf("%s",s); ql=getint(); qr=getint(); 69 if (s[0]==‘Q‘) {ans=0; query(1,1,n); printf("%d\n",ans);} 70 if (s[0]==‘U‘) update(1,1,n,ql,qr); 71 } 72 } 73 return 0; 74 }
普通线段树(436MS 3996K)
1 //HDOJ 1754 2 #include<cmath> 3 #include<vector> 4 #include<cstdio> 5 #include<cstring> 6 #include<cstdlib> 7 #include<iostream> 8 #include<algorithm> 9 #define rep(i,n) for(int i=0;i<n;++i) 10 #define F(i,j,n) for(int i=j;i<=n;++i) 11 #define D(i,j,n) for(int i=j;i>=n;--i) 12 #define pb push_back 13 #define CC(a,b) memset(a,b,sizeof(a)) 14 using namespace std; 15 int getint(){ 16 int v=0,sign=1; char ch=getchar(); 17 while(!isdigit(ch)) {if(ch==‘-‘) sign=-1; ch=getchar();} 18 while(isdigit(ch)) {v=v*10+ch-‘0‘; ch=getchar();} 19 return v*sign; 20 } 21 const int N=200010,INF=~0u>>2; 22 const double eps=1e-8; 23 /*******************template********************/ 24 25 int t[N<<2],n,m; 26 void update(int p,int v){ 27 for(t[p+=n]=v,p>>=1;p;p>>=1) 28 t[p]=max(t[p+p],t[p+p^1]); 29 } 30 int ans; 31 void query(int l,int r){ 32 for(l=l+n-1,r=r+n+1;l^r^1;l>>=1,r>>=1){ 33 if (!(l&1)) ans=max(t[l^1],ans); 34 if ( r&1) ans=max(t[r^1],ans); 35 } 36 } 37 int main(){ 38 #ifndef ONLINE_JUDGE 39 freopen("input.txt","r",stdin); 40 // freopen("output.txt","w",stdout); 41 #endif 42 while(scanf("%d%d",&n,&m)!=EOF){ 43 CC(t,0); 44 F(i,1,n) t[i+n]=getint(); 45 D(i,n-1,1) t[i]=max(t[2*i],t[2*i+1]);//这句就是build建树…… 46 char s[4]; 47 int x,y; 48 F(i,1,m){ 49 scanf("%s",s); x=getint(); y=getint(); 50 if (s[0]==‘Q‘) {ans=0; query(x,y); printf("%d\n",ans);} 51 if (s[0]==‘U‘) update(x,y); 52 } 53 } 54 return 0; 55 }
zkw线段树(218MS 4296K)
时间: 2024-10-15 07:20:31