[kuangbin带你飞]专题七 线段树
2015-10-01 15:05
429 查看
点击打开链接
A(hdu 1166 敌兵布阵 )中文体面,线段树单点更新,求一段区间和
F(zoj 1610 Count the Colors)
G 简单的单点更新
P(hdu 1542 Atlantis)扫描线求矩形面积
A(hdu 1166 敌兵布阵 )中文体面,线段树单点更新,求一段区间和
#include<stdio.h> #include<string.h> #include<stack> #include<string> #include<math.h> #include<queue> #include<set> #include<algorithm> #include<iostream> #include<vector> #include<map> using namespace std; #define LL long long #define inf 1<<31 #define N 50010 #define mod 1000000007 struct node { int l,r,sum; }tree[N<<2]; void pushup(int rt) { tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum; } void build(int l,int r,int rt) { tree[rt].l=l; tree[rt].r=r; tree[rt].sum=0; if(l==r) { scanf("%d",&tree[rt].sum); return ; } int mid=(tree[rt].l+tree[rt].r)>>1; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); pushup(rt); } void updata(int x,int y,int rt) { if(tree[rt].l==tree[rt].r) { tree[rt].sum+=y; return ; } int mid=(tree[rt].l+tree[rt].r)>>1; if(x<=mid) updata(x,y,rt<<1); else updata(x,y,rt<<1|1); pushup(rt); } int query(int x,int y,int rt) { if(tree[rt].l==x&&tree[rt].r==y) { return tree[rt].sum; } int mid=(tree[rt].l+tree[rt].r)>>1; if(y<=mid) return query(x,y,rt<<1); else if(x>mid) return query(x,y,rt<<1|1); else return query(x,mid,rt<<1)+query(mid+1,y,rt<<1|1); } int main() { int i,j,n,m,t,x,y,ca=0; scanf("%d",&t); while(t--) { scanf("%d",&n); build(1,n,1); char s[10]; printf("Case %d:\n",++ca); while(scanf("%s",s),s[0]!='E') { scanf("%d%d",&x,&y); if(s[0]=='Q') printf("%d\n",query(x,y,1)); else if(s[0]=='A') updata(x,y,1); else if(s[0]=='S') updata(x,-y,1);; } } return 0; }B(hdu 1754 I Hate It)中文体面,线段树单点更新,求区间最大值
#include<stdio.h> #include<string.h> #include<stack> #include<string> #include<math.h> #include<queue> #include<set> #include<algorithm> #include<iostream> #include<vector> #include<map> using namespace std; #define LL long long #define inf 1<<31 #define N 200010 struct node { int l,r,Max; }tree[N<<2]; void build(int l,int r,int rt) { tree[rt].l=l; tree[rt].r=r; if(l==r) { scanf("%d",&tree[rt].Max); return ; } int mid=(r+l)>>1; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); tree[rt].Max=max(tree[rt<<1].Max,tree[rt<<1|1].Max); } int ans; void query(int l,int r,int rt) { if(tree[rt].l==l&&tree[rt].r==r) { ans=max(ans,tree[rt].Max); return ; } int mid=(tree[rt].l+tree[rt].r)>>1; if(l>mid) query(l,r,rt<<1|1); else if(r<=mid) query(l,r,rt<<1); else { query(l,mid,rt<<1); query(mid+1,r,rt<<1|1); } } void updata(int x,int y,int rt) { if(tree[rt].l==tree[rt].r) { tree[rt].Max=y; return ; } int mid=(tree[rt].l+tree[rt].r)>>1; if(x>mid) updata(x,y,rt<<1|1); else updata(x,y,rt<<1); tree[rt].Max=max(tree[rt<<1].Max,tree[rt<<1|1].Max); } int main() { int i,j,n,m,x,y; char s[3]; while(scanf("%d%d",&n,&m)!=-1) { build(1,n,1); for(i=1;i<=m;i++) { scanf("%s%d%d",s,&x,&y); if(s[0]=='Q') { ans=-1; query(x,y,1); printf("%d\n",ans); } else updata(x,y,1); } } return 0; }C(poj 3468 A Simple Problem with Integers)线段树的区间更新区间求和
#include<stdio.h> #include<string.h> #include<stack> #include<string> #include<math.h> #include<queue> #include<set> #include<algorithm> #include<iostream> #include<vector> #include<map> using namespace std; #define LL long long #define inf 1<<31 #define N 100010 struct node { int l,r; LL sum,add;//加的数不直接更新到叶子节点,而是先存到add中 }tree[N<<2]; void pushup(int rt) { tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum; } void build(int l,int r,int rt) { tree[rt].l=l;tree[rt].r=r; tree[rt].sum=tree[rt].add=0; if(l==r) { scanf("%lld",&tree[rt].sum); return ; } int mid=(tree[rt].l+tree[rt].r)>>1; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); pushup(rt); } void pushdown(int rt) { int len=tree[rt].r-tree[rt].l+1; tree[rt<<1].add+=tree[rt].add; tree[rt<<1|1].add+=tree[rt].add; tree[rt<<1].sum+=tree[rt].add*(len-len/2); tree[rt<<1|1].sum+=tree[rt].add*(len/2); tree[rt].add=0; } LL query(int x,int y,int rt) { if(tree[rt].l==x&&tree[rt].r==y) return tree[rt].sum; int mid=(tree[rt].l+tree[rt].r)>>1; pushdown(rt); if(y<=mid) return query(x,y,rt<<1); else if(x>mid) return query(x,y,rt<<1|1); else return query(x,mid,rt<<1)+query(mid+1,y,rt<<1|1); } void updata(int x,int y,LL z,int rt) { if(tree[rt].l==x&&tree[rt].r==y) { tree[rt].add+=z; tree[rt].sum+=(y-x+1)*z; return ; } int mid=(tree[rt].l+tree[rt].r)>>1; pushdown(rt); if(y<=mid) updata(x,y,z,rt<<1); else if(x>mid) updata(x,y,z,rt<<1|1); else { updata(x,mid,z,rt<<1); updata(mid+1,y,z,rt<<1|1); } pushup(rt); } int main() { int i,j,n,m; char s[3]; int x,y; LL z; while(scanf("%d%d",&n,&m)!=-1) { build(1,n,1); while(m--) { scanf("%s",s); if(s[0]=='Q') { scanf("%d%d",&x,&y); printf("%lld\n",query(x,y,1)); } else { scanf("%d%d%lld",&x,&y,&z); updata(x,y,z,1); } } } return 0; }D(poj 2528 Mayor's posters )线段树+离散化,就是在墙上贴海报,当前贴的海报可以把以前的海报覆盖掉,问最后还能看见多少海报
#include<stdio.h> #include<string.h> #include<stack> #include<string> #include<math.h> #include<queue> #include<set> #include<algorithm> #include<iostream> #include<vector> #include<map> using namespace std; #define LL long long #define inf 1<<31 #define N 20010 struct node { int l,r,c; }tree[N<<2]; struct Line { int l,r; }a ; int key ,tot,ans; bool mark ; void build(int l,int r,int rt) { tree[rt].l=l;tree[rt].r=r; tree[rt].c=0; if(l==r) return ; int mid=(tree[rt].l+tree[rt].r)>>1; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); } int find_p(int x) { int low=1,high=tot; while(low<=high) { int mid=(low+high)>>1; if(key[mid]==x) return mid; else if(x<key[mid]) high=mid-1; else low=mid+1; } } void updata(int l,int r,int c,int rt) { if(tree[rt].l==l&&tree[rt].r==r) { tree[rt].c=c; return ; } if(tree[rt].c) { tree[rt<<1].c=tree[rt<<1|1].c=tree[rt].c; tree[rt].c=0; } int mid=(tree[rt].l+tree[rt].r)>>1; if(r<=mid) updata(l,r,c,rt<<1); else if(l>mid) updata(l,r,c,rt<<1|1); else { updata(l,mid,c,rt<<1); updata(mid+1,r,c,rt<<1|1); } } void query(int rt) { if(tree[rt].c) { if(mark[tree[rt].c]==0) { mark[tree[rt].c]=1; ans++; } return ; } query(rt<<1); query(rt<<1|1); } int main() { int i,j,n,m,t; scanf("%d",&t); while(t--) { memset(mark,0,sizeof(mark)); scanf("%d",&n); tot=0; for(i=1;i<=n;i++) { scanf("%d%d",&a[i].l,&a[i].r); key[++tot]=a[i].l;key[++tot]=a[i].r; } sort(key+1,key+1+tot); tot=unique(key+1,key+1+tot)-(key+1);//数组去重 // printf("%d\n",tot); build(1,tot,1); for(i=1;i<=n;i++)//离散化 { int L=find_p(a[i].l); int R=find_p(a[i].r); updata(L,R,i,1); } ans=0; query(1); printf("%d\n",ans); } return 0; }E(hdu 1698 just a hook) 还是区间操作,代码点击打开链接
F(zoj 1610 Count the Colors)
#include<stdio.h> #include<string.h> #include<stack> #include<string> #include<math.h> #include<queue> #include<set> #include<algorithm> #include<iostream> #include<vector> #include<map> using namespace std; #define LL long long #define inf 1<<31 #define N 8010 struct node { int l,r,c; }tree[N<<2]; int col ,ans ;//col[i]是i位置颜色的种类,ans[i]是颜色i的段数 void build(int l,int r,int rt) { tree[rt].l=l; tree[rt].r=r; tree[rt].c=-1; if(r-l==1) return ;//涂色是一小段区间 int mid=(l+r)>>1; build(l,mid,rt<<1); build(mid,r,rt<<1|1); } void updata(int l,int r,int c,int rt) { if(tree[rt].l==l&&tree[rt].r==r) { tree[rt].c=c; return ; } if(tree[rt].r-tree[rt].l==1) return ; int mid=(tree[rt].l+tree[rt].r)>>1; if(tree[rt].c!=-1) { tree[rt<<1].c=tree[rt<<1|1].c=tree[rt].c; tree[rt].c=-1; } if(r<=mid) updata(l,r,c,rt<<1); else if(l>=mid) updata(l,r,c,rt<<1|1); else { updata(l,mid,c,rt<<1); updata(mid,r,c,rt<<1|1); } } void query(int rt) { if(tree[rt].c!=-1) { for(int i=tree[rt].l;i<tree[rt].r;i++) col[i]=tree[rt].c; return ; } if(tree[rt].r-tree[rt].l==1) return ; query(rt<<1); query(rt<<1|1); } int main() { int i,j,n,m; while(scanf("%d",&n)!=EOF) { int x,y,z; build(0,8000,1); for(i=0;i<n;i++) { scanf("%d%d%d",&x,&y,&z); updata(x,y,z,1); } memset(ans,0,sizeof(ans)); memset(col,-1,sizeof(col)); query(1); for(i=0;i<=8000;i++) { if(col[i]==-1) continue; if(col[i]!=col[i+1]) ans[col[i]]++; } for(i=0;i<=8000;i++) { if(ans[i]==0) continue; printf("%d %d\n",i,ans[i]); } puts(""); } return 0; }
G 简单的单点更新
#include<stdio.h> #include<string.h> #include<stack> #include<string> #include<math.h> #include<queue> #include<set> #include<algorithm> #include<iostream> #include<vector> #include<map> using namespace std; #define LL long long #define inf 1<<30 #define N 50010 struct node { int l,r,Min,Max; }tree[N<<2]; int resmin,resmax; void build(int l,int r,int rt) { tree[rt].l=l; tree[rt].r=r; if(l==r) { scanf("%d",&tree[rt].Min); tree[rt].Max=tree[rt].Min; return ; } int mid=(r+l)>>1; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); tree[rt].Min=min(tree[rt<<1].Min,tree[rt<<1|1].Min); tree[rt].Max=max(tree[rt<<1].Max,tree[rt<<1|1].Max); } void query(int l,int r,int rt) { if(tree[rt].l==l&&tree[rt].r==r) { resmin=min(resmin,tree[rt].Min); resmax=max(resmax,tree[rt].Max); return ; } int mid=(tree[rt].l+tree[rt].r)>>1; if(l>mid) query(l,r,rt<<1|1); else if(r<=mid) query(l,r,rt<<1); else { query(l,mid,rt<<1); query(mid+1,r,rt<<1|1); } } int main() { int m,n,j,i,a,b; while(scanf("%d%d",&n,&m)!=-1) { build(1,n,1); for(i=0;i<m;i++) { resmin=inf;resmax=-inf; scanf("%d%d",&a,&b); query(a,b,1); printf("%d\n",resmax-resmin); } } return 0; }I(hdu 1540 Tunnel Warfare)单点更新,区间合并、查询
#include<stdio.h> #include<string.h> #include<stack> #include<string> #include<math.h> #include<queue> #include<set> #include<algorithm> #include<iostream> #include<vector> #include<map> using namespace std; #define LL long long #define inf 1<<30 #define N 50010 struct node { int l,r,lans,rans,ans; }tree[N<<2]; void pushup(int rt) { if(tree[rt<<1].ans==tree[rt<<1].r-tree[rt<<1].l+1) tree[rt].lans=tree[rt<<1].ans+tree[rt<<1|1].lans; else tree[rt].lans=tree[rt<<1].lans; if(tree[rt<<1|1].ans==tree[rt<<1|1].r-tree[rt<<1|1].l+1) tree[rt].rans=tree[rt<<1|1].ans+tree[rt<<1].rans; else tree[rt].rans=tree[rt<<1|1].rans; tree[rt].ans= max(max(tree[rt<<1].ans,tree[rt<<1|1].ans),tree[rt<<1].rans+tree[rt<<1|1].lans); } void build(int l,int r,int rt) { tree[rt].l=l;tree[rt].r=r; tree[rt].lans=tree[rt].rans=tree[rt].ans=r-l+1; if(l==r) return ; int mid=(l+r)>>1; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); } void updata(int x,int rt,int c) { if(tree[rt].l==tree[rt].r) { tree[rt].ans=tree[rt].lans=tree[rt].rans=c; return ; } int mid=(tree[rt].l+tree[rt].r)>>1; if(x<=mid) updata(x,rt<<1,c); else updata(x,rt<<1|1,c); pushup(rt); } int query(int x,int rt) { if(tree[rt].ans==0||tree[rt].ans==tree[rt].r-tree[rt].l+1) return tree[rt].ans; int mid=(tree[rt].l+tree[rt].r)>>1; if(x<=mid) { if(x>=tree[rt<<1].r-tree[rt<<1].rans+1) return tree[rt<<1].rans+tree[rt<<1|1].lans; else return query(x,rt<<1); } else { if(x<=tree[rt<<1|1].l+tree[rt<<1|1].lans-1) return tree[rt<<1].rans+tree[rt<<1|1].lans; else return query(x,rt<<1|1); } } int main() { int i,j,n,m,x; char str[3]; while(scanf("%d%d",&n,&m)!=-1) { stack<int>s; while(!s.empty()) s.pop(); build(1,n,1); while(m--) { scanf("%s",str); if(str[0]=='D') { scanf("%d",&x); updata(x,1,0); s.push(x); } else if(str[0]=='Q') { scanf("%d",&x); printf("%d\n",query(x,1)); } else { x=s.top(); s.pop(); updata(x,1,1); } } } return 0; }
P(hdu 1542 Atlantis)扫描线求矩形面积
#include<stdio.h> #include<string.h> #include<stack> #include<string> #include<math.h> #include<queue> #include<set> #include<algorithm> #include<iostream> #include<vector> #include<map> using namespace std; #define LL long long #define inf 1<<30 #define N 210 struct node { int l,r; int c;//c用来记录重叠情况 double cnt,lf,rf; //cnt用来计算y的长度,rf,lf分别是对应的左右真实的浮点数端点 }tree[N<<2]; struct Line { double x,y1,y2; int f; }line ; //把一段段平行于y轴的线段表示成数组 , //x是线段的x坐标,y1,y2线段对应的下端点和上端点的坐标 //一个矩形 ,左边的那条边f为1,右边的为-1, //用来记录重叠情况,可以根据这个来计算,nod节点中的c double y ;//记录y坐标的数组 bool cmp(Line a,Line b) { return a.x<b.x; } void build(int l,int r,int rt) { tree[rt].l=l;tree[rt].r=r; tree[rt].cnt=tree[rt].c=0; tree[rt].lf=y[l];tree[rt].rf=y[r]; if(l+1==r) return ; int mid=(l+r)>>1; build(l,mid,rt<<1); build(mid,r,rt<<1|1); } void calen(int rt) { if(tree[rt].c>0) { tree[rt].cnt=tree[rt].rf-tree[rt].lf; return ; } if(tree[rt].l+1==tree[rt].r) tree[rt].cnt=0; else tree[rt].cnt=tree[rt<<1].cnt+tree[rt<<1|1].cnt; } void updata(int rt,Line e) { if(e.y1==tree[rt].lf&&tree[rt].rf==e.y2) { tree[rt].c+=e.f; calen(rt); return ; } if(e.y2<=tree[rt<<1].rf) updata(rt<<1,e); else if(e.y1>=tree[rt<<1|1].lf) updata(rt<<1|1,e); else { Line tmp=e; tmp.y2=tree[rt<<1].rf; updata(rt<<1,tmp); tmp=e; tmp.y1=tree[rt<<1|1].lf; updata(rt<<1|1,tmp); } calen(rt); } int main() { int i,n,j,t,ca=1; double x1,x2,y1,y2; while(scanf("%d",&n),n) { t=1; for(i=1;i<=n;i++) { scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); line[t].x=x1;line[t].y1=y1;line[t].y2=y2;line[t].f=1; y[t]=y1; t++; line[t].x=x2;line[t].y1=y1;line[t].y2=y2;line[t].f=-1; y[t]=y2; t++; } sort(line+1,line+t,cmp); sort(y+1,y+t); build(1,t-1,1); updata(1,line[1]); double ans=0; for(i=2;i<t;i++) { ans+=tree[1].cnt*(line[i].x-line[i-1].x); updata(1,line[i]); } printf("Test case #%d\nTotal explored area: %.2f\n\n",ca++,ans); } return 0; }
相关文章推荐
- 第三方类库masonry(自动布局)的使用
- jQuery 遍历 - each() 方法
- 第一个OC程序
- 如何检查Linux服务器是否受到DDOS攻击
- debian 8 安装 codeblocks
- JSP九大内置对象
- LightOJ 1282 Leading and Trailing
- Linux 命令 - rm: 删除文件和目录
- 项目质量管理重点
- Redis配置文件详解
- JAVA实现替换空格(《剑指offer》)
- c#导出(一) 到txt
- DIV的属性
- zw版【转发·台湾nvp系列Delphi例程】HALCON TestSubsetRegio
- 进制转换
- 秒针系统网络广告交易平台介绍
- VC 设置炫彩窗口全屏
- 秒针系统网络广告交易平台介绍
- 秒针系统网络广告交易平台介绍
- JavaScript parseInt() 函数