[Noi2016十连测第三场]线段树
Posted oyzx~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Noi2016十连测第三场]线段树相关的知识,希望对你有一定的参考价值。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 using namespace std; 7 #define maxn 100005 8 #define maxk 4000005 9 int n,m,q,tot,t1,t2,ans,L[maxn][18],R[maxn][18]; 10 void read(int &x){ 11 x=0; int f=1; char ch; 12 for (ch=getchar();!isdigit(ch);ch=getchar()) if (ch==\'-\') f=-1; 13 for (;isdigit(ch);ch=getchar()) x=x*10+ch-\'0\'; x*=f; 14 } 15 struct Seg{ 16 int sm; 17 }tree1[maxk]; 18 struct mess{ 19 int l,r; 20 }chg[maxn]; 21 struct Segment{ 22 void maketree(int k,int l,int r){ 23 if (l==r){ 24 read(tree1[k].sm); 25 return; 26 }int mid=(l+r)>>1; 27 maketree(k<<1,l,mid),maketree(k<<1|1,mid+1,r); 28 tree1[k].sm=max(tree1[k<<1].sm,tree1[k<<1|1].sm); 29 } 30 void change(int k,int l,int r,int x,int y){ 31 if (l==r&&r==x){ 32 tree1[k].sm=y; 33 return; 34 }int mid=(l+r)>>1; 35 if (x<=mid) change(k*2,l,mid,x,y); 36 else change(k<<1|1,mid+1,r,x,y); 37 tree1[k].sm=max(tree1[k<<1].sm,tree1[k<<1|1].sm); 38 } 39 void query(int k,int l,int r,int x,int y){ 40 if (l>=x&&r<=y){ 41 ans=max(ans,tree1[k].sm); 42 return; 43 } int mid=(l+r)>>1; 44 if (x<=mid) query(k<<1,l,mid,x,y); 45 if (y>mid) query(k<<1|1,mid+1,r,x,y); 46 } 47 }Tree1; 48 struct SEg{ 49 int cover; 50 }tree2[maxk]; 51 int root[maxn],son[maxk][2]; 52 struct SEgment{ 53 void insert(int p,int &k,int l,int r,int x,int y,int z){ 54 k=++tot,tree2[k]=tree2[p]; son[k][0]=son[p][0],son[k][1]=son[p][1]; 55 if (l>=x&&r<=y){ 56 tree2[k].cover=z; 57 return; 58 }int mid=(l+r)/2; 59 if (x<=mid) insert(son[p][0],son[k][0],l,mid,x,y,z); 60 if (y>mid) insert(son[p][1],son[k][1],mid+1,r,x,y,z); 61 } 62 void query(int k,int l,int r,int x){ 63 t1=max(t1,tree2[k].cover); 64 if (l==r) return; 65 int mid=(l+r)>>1; 66 if (x<=mid) query(son[k][0],l,mid,x); 67 else query(son[k][1],mid+1,r,x); 68 } 69 }Tree2; 70 struct Fseg{ 71 int cover; 72 }tree3[maxk]; 73 struct Fsegment{ 74 void insert(int k,int l,int r,int x,int y,int z){ 75 if (l>=x&&r<=y){ 76 tree3[k].cover=z; 77 return; 78 }int mid=(l+r)>>1; 79 if (x<=mid) insert(k<<1,l,mid,x,y,z); 80 if (y>mid) insert(k<<1|1,mid+1,r,x,y,z); 81 } 82 void query(int k,int l,int r,int x){ 83 t1=max(t1,tree3[k].cover); 84 if (l==r) return; 85 int mid=(l+r)>>1; 86 if (x<=mid) query(k<<1,l,mid,x); 87 else query(k<<1|1,mid+1,r,x); 88 } 89 }Tree3; 90 int main(){ 91 read(n),read(m),read(q); 92 Tree1.maketree(1,1,n); 93 tot=0,memset(root,0,sizeof(root)); 94 memset(L,0,sizeof(L)); 95 memset(R,0,sizeof(R)); 96 for (int i=1;i<=m;i++) read(chg[i].l),read(chg[i].r); 97 for (int i=1;i<=m;i++) Tree2.insert(root[i-1],root[i],1,n,chg[i].l,chg[i].r,i); 98 for (int i=1;i<=m;i++){ 99 t1=0; Tree3.query(1,1,n,chg[i].l); L[i][0]=t1; 100 t1=0; Tree3.query(1,1,n,chg[i].r); R[i][0]=t1; 101 Tree3.insert(1,1,n,chg[i].l,chg[i].r,i); 102 } 103 for (int i=1;i<=17;i++){ 104 for (int j=1;j<=m;j++){ 105 L[j][i]=L[L[j][i-1]][i-1]; 106 R[j][i]=R[R[j][i-1]][i-1]; 107 } 108 } 109 for (int type,l,r,w,i=1;i<=q;i++){ 110 read(type),read(l),read(r); 111 if (type==1) Tree1.change(1,1,n,l,r); 112 else{ 113 read(w); 114 t1=0; Tree2.query(root[r],1,n,w); t2=t1; 115 if (t1>=l){ 116 for (int j=17;j>=0;j--) if (L[t1][j]&&L[t1][j]>=l) t1=L[t1][j]; 117 for (int j=17;j>=0;j--) if (R[t2][j]&&R[t2][j]>=l) t2=R[t2][j]; 118 ans=0,t1=chg[t1].l,t2=chg[t2].r,Tree1.query(1,1,n,t1,t2); 119 }else ans=0,Tree1.query(1,1,n,w,w); 120 printf("%d\\n",ans); 121 } 122 } 123 return 0; 124 }
题目大意:线段树
【问题描述】 以上是关于[Noi2016十连测第三场]线段树的主要内容,如果未能解决你的问题,请参考以下文章
小