第一次写线段树题,写的是静态的飘过~~~
线段树:它主要用于处理一段连续区间的插入,查找,统计,查询等操作。
复杂度: 设区间长度是n,所有操作的复杂度是logn级别。
一线段树的建图有两种。
1、最后一层建成线段,就是所有区间都是开区间,最后一层是[1,2] [2,3] [3,4]。。。。。。
2、最后一层建成点,类似[1,1] [2,2]..
二、更新
1、注意更新父节点对子节点的影响。
2、注意更新子节点对父节点的影响。
AC代码:
#include<iostream> #include<string.h> #include<algorithm> #define L(x) (x<<1) #define R(x) (x<<1|1) #define MID(x,y)((x+y)>>1) using namespace std; typedef struct str { int l; int r; int key; }Node; Node node[100001*4]; void build(int t,int l,int r)//建树 { node[t].l=l;node[t].r=r; node[t].key=1; if(l==r-1) return; int mid=MID(l,r); build(L(t),l,mid); build(R(t),mid,r); } void update(int t,int l,int r,int sum)//更新 { if(l==node[t].l&&r==node[t].r) { node[t].key=sum; return; } if(node[t].key>0) { node[L(t)].key=node[t].key; node[R(t)].key=node[t].key; node[t].key=-1; } int mid=MID(node[t].l,node[t].r); if(l>=mid) update(R(t),l,r,sum); else{ if(r<=mid) update(L(t),l,r,sum); else { update(R(t),mid,r,sum); update(L(t),l,mid,sum); } } } int Quary(int t,int l,int r)//查找 { if(node[t].key>0) return node[t].key*(r-l); int mid=MID(node[t].l,node[t].r); return Quary(R(t),mid,r)+Quary(L(t),l,mid); /*if(l>=mid) return Quary(R(t),l,r); else { if(r<=mid) return Quary(L(t),l,r); else { return Quary(R(t),mid,r)+Quary(L(t),l,mid); } }*/ } int main() { int T; cin>>T; int tot=0; while(T--) { int n; cin>>n; build(1,0,n); int m; cin>>m; while(m--) { int x,y,z; cin>>x>>y>>z; update(1,x-1,y,z); } printf("Case %d: The total value of the hook is %d.\n",++tot,Quary(1,0,n)); }return 0; }
动态:
#include<iostream> #include<string.h> #include<cstdio> #include<algorithm> using namespace std; typedef struct NODE { struct NODE *lc,*rc; int ld,rd; int key; NODE() { key=1; } }*Node,T; class rmq{ public: Node root; rmq() { root=new T; } ~rmq() { delete root; } Node build(int a,int b); void update(Node root ,int l,int r,int sum); int Quary(Node root,int l,int r); }; Node rmq::build(int a,int b) { Node root=new T; root->ld=a; root->rd=b; if(a==b-1) return root; int mid=(a+b)>>1; root->lc=build(a,mid); root->rc=build(mid,b); return root; } void rmq::update(Node root,int l,int r,int sum) { if(root->ld==l&&root->rd==r) { root->key=sum; return; } if(root->key==sum) return; if(root->key>0) { root->lc->key=root->key; root->rc->key=root->key; root->key=-1; } int mid=(root->ld+root->rd)>>1; if(l>=mid) update(root->rc,l,r,sum); else { if(r<=mid) update(root->lc,l,r,sum); else { update(root->lc,l,mid,sum); update(root->rc,mid,r,sum); } } } int rmq::Quary(Node root,int l,int r) { if(root->key>0) return root->key*(root->rd-root->ld); int mid=(root->ld+root->rd)>>1; return Quary(root->lc,l,mid)+Quary(root->rc,mid,r); } int main() { int T; cin>>T; int tot=0; while(T--) { int n; cin>>n; rmq s; s.root=s.build(0,n); int m; cin>>m; while(m--) { int x,y,z; cin>>x>>y>>z; s.update(s.root,x-1,y,z); } printf("Case %d: The total value of the hook is %d.\n",++tot,s.Quary(s.root,0,n)); }return 0; }