hdu 1823 Luck and Love

来源:互联网 发布:数据魔方有什么用 编辑:程序博客网 时间:2024/04/29 07:57
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <algorithm>using namespace std;const int N=4050;int Max;struct cnode{int cl,cr;int sum;};struct node{int l,r;cnode ctree[N];}tree[N];int max(int a,int b){return a>b?a:b;}void cbuild(int root,int croot,int cl,int cr)//建立子树{tree[root].ctree[croot].cl=cl;tree[root].ctree[croot].cr=cr;tree[root].ctree[croot].anum=0;tree[root].ctree[croot].bnum=0;//printf("%d %d\n",tree[root].ctree[croot].cl,tree[root].ctree[croot].cr);if(cl==cr){if(cl%2==0)tree[root].ctree[croot].bnum=1;elsetree[root].ctree[croot].anum=1;}int cmid=(cl+cr)>>1;cbuild(root,croot<<1,cl,cmid);cbuild(root,croot<<1|1,cmid+1,cr);tree[root].ctree[croot].anum+=tree[root].ctree[croot<<1].anum+tree[root].ctree[croot<<1|1].anum;tree[root].ctree[croot].bnum+=tree[root].ctree[croot<<1].bnum+tree[root].ctree[croot<<1|1].bnum;}void build(int root,int l,int r,int cl,int cr)//建立母树{tree[root].l=l;tree[root].r=r;cbuild(root,1,cl,cr);if(l==r){return ;}int mid=(r+l)>>1;build(root<<1,l,mid,cl,cr);build(root<<1|1,mid+1,r,cl,cr);}void cupdata(int step,int s,int a,int sum)//更新到子树的线段{if(tree[step].ctree[s].cl==tree[step].ctree[s].cr){tree[step].ctree[s].sum=max(tree[step].ctree[s].sum,sum);return ;}int cmid=(tree[step].ctree[s].cl+tree[step].ctree[s].cr)>>1;if(a<=cmid){cupdata(step,s<<1,a,sum);}else{cupdata(step,s<<1|1,a,sum);}tree[step].ctree[s].sum=max(tree[step].ctree[s].sum,sum);}void updata(int step,int h,int a,int sum)//更新母树线段{cupdata(step,1,a,sum);//首先要先更新到子树中去if(tree[step].l==tree[step].r){return ;}int mid=(tree[step].r+tree[step].l)>>1;if(h<=mid){updata(step<<1,h,a,sum);}else{updata(step<<1|1,h,a,sum);}}void subcompute(int step,int s,int a1,int a2)//在子树中统计{if(tree[step].ctree[s].cl==a1&&tree[step].ctree[s].cr==a2){if(Max<tree[step].ctree[s].sum){Max=tree[step].ctree[s].sum;}return ;}int cmid=(tree[step].ctree[s].cl+tree[step].ctree[s].cr)>>1;if(a2<=cmid){subcompute(step,s<<1,a1,a2);}else{if(a1>cmid){subcompute(step,s<<1|1,a1,a2);}else{subcompute(step,s<<1,a1,cmid);subcompute(step,s<<1|1,cmid+1,a2);}}}void compute(int step,int h1,int h2,int a1,int a2){if(tree[step].l==h1&&h2==tree[step].r){subcompute(step,1,a1,a2);return ;}int mid=(tree[step].l+tree[step].r)>>1;if(h2<=mid){compute(step<<1,h1,h2,a1,a2);}else{if(h1>mid){compute(step<<1|1,h1,h2,a1,a2);}else{compute(step<<1,h1,mid,a1,a2);compute(step<<1|1,mid+1,h2,a1,a2);}}}int main(){int n,h,x2,y2,x1,y1,r;char ch[10];double a,f,x,y;int sum;while(scanf("%d",&n)){if(n==0)break;build(1,100,200,0,1000);while(n--){scanf("%s",ch);if(ch[0]=='I'){scanf("%d%lf%lf",&h,&a,&f);r=(int)(a*10);sum=(int)(f*10);updata(1,h,r,sum);}else{scanf("%d%d%lf%lf",&x1,&y1,&x,&y);x2=(int)(x*10);y2=(int)(y*10);if(x1>y1)swap(x1,y1);if(x2>y2)swap(x2,y2);Max=0;compute(1,x1,y1,x2,y2);double ans=Max/10.0;if(ans<=0){printf("-1\n");}else{printf("%.1lf\n",ans);}}}}return 0;}


终于对二维线段树有了一个大概的理解!

二维线段树有两种建树方法:

1:树中有树,就是建立母树,再在母树中建立子树

2:四分思想,每个节点有四个孩子

我用的是第一种方法

 

原创粉丝点击