zoj 3299 线段树
来源:互联网 发布:zip在linux下解压 编辑:程序博客网 时间:2024/05/23 15:06
题意:从空中落下的一排一排的砖头落在空中的线段上
然后会累计
这题有点扫描线的意思 也是把线段搞成点树
是个好题啊 但是为什么需要开100W?换了很多姿势都过不了!
原因
数组然后开大一点马上MLE 开小马上WA (不能全用左移啊 只能乖乖*10了)
然后献上两种姿势:
最土但是最易于理解的双标记法:
#include<string.h>#include<stdio.h>#include<cstdio>#include<iostream>#include<algorithm>using namespace std;#define maxn 100111#define LL long long#define ls (rt<<1)#define rs (rt<<1|1)#define mid ((l+r)>>1)int set[maxn<<4];LL sum[maxn<<4];LL add[maxn*10];int x[maxn<<2];void up(int rt,int l,int r){sum[rt]=sum[ls]+sum[rs];}void down(int rt,int l,int r){ if(set[rt]!=-1){ sum[ls]=sum[rs]=0;add[ls]=add[rs]=0; set[ls]=set[rs]=1; set[rt]=-1; } if(add[rt]){ sum[ls]+=(LL)((x[mid+1]-x[l])*add[rt]); sum[rs]+=(LL)((x[r+1]-x[mid+1])*add[rt]); add[ls]+=add[rt]; add[rs]+=add[rt]; add[rt]=0; }}void ins(int rt,int l,int r,int L,int R){ if(L<=l&&r<=R){ sum[rt]+=(LL)(x[r+1]-x[l]); add[rt]++; return ; } down(rt,l,r); if(L<=mid)ins(ls,l,mid,L,R); if(mid<R)ins(rs,mid+1,r,L,R); up(rt,l,r);}void _set(int rt,int l,int r,int L,int R){ if(L<=l&&r<=R){ set[rt]=1;sum[rt]=add[rt]=0; return ; } down(rt,l,r); if(L<=mid)_set(ls,l,mid,L,R); if(mid<R)_set(rs,mid+1,r,L,R); up(rt,l,r);}LL query(int rt,int l,int r,int L,int R){ // printf("%d %d %d\n",l,r,sum[rt]);// if(set[rt]!=-1)return 0; if(L<=l&&r<=R)return sum[rt]; down(rt,l,r); LL res=0; if(L<=mid)res+=query(ls,l,mid,L,R); if(mid<R)res+=query(rs,mid+1,r,L,R); return res;}int ll[maxn<<1],rr[maxn<<1];int n,m,cnt,tmp;struct line{ int l,r,h; int id; line(int l=0,int r=0,int h=0):l(l),r(r),h(h){}}e[maxn];LL ans[maxn];int cmp(line x,line y){return x.h>y.h;}int main(){ while(~scanf("%d%d",&n,&m)){ memset(set,-1,sizeof set); memset(sum,0,sizeof sum); memset(add,0,sizeof add); cnt=0; for(int i=0;i<n;++i){ scanf("%d%d",&ll[i],&rr[i]); x[cnt++]=ll[i];x[cnt++]=rr[i]; } for(int i=0;i<m;++i){ scanf("%d%d%d",&e[i].l,&e[i].r,&e[i].h); x[cnt++]=e[i].l;x[cnt++]=e[i].r; e[i].id=i; } sort(x,x+cnt); tmp=(int)(unique(x,x+cnt)-x); // for(int i=0;i<tmp;++i)printf("%d ",x[i]);printf("\n"); sort(e,e+m,cmp); for(int i=0;i<n;++i){ ll[i]=(int)(lower_bound(x,x+tmp,ll[i])-x); rr[i]=(int)(lower_bound(x,x+tmp,rr[i])-x)-1; ins(1,0,tmp-1,ll[i],rr[i]); } for(int i=0;i<m;++i){ e[i].l=(int)(lower_bound(x,x+tmp,e[i].l)-x); e[i].r=(int)(lower_bound(x,x+tmp,e[i].r)-x)-1;// printf("%d %d\n",e[i].l,e[i].r); ans[e[i].id]=query(1,0,tmp-1,e[i].l,e[i].r); _set(1,0,tmp-1,e[i].l,e[i].r); } for(int i=0;i<m;++i)printf("%lld\n",ans[i]); printf("\n"); } return 0;}
比较厉害的标记不下传法:
#include<string.h>#include<stdio.h>#include<cstdio>#include<iostream>#include<algorithm>using namespace std;#define maxn 100111#define LL long long#define ls (rt<<1)#define rs (rt<<1|1)#define mid ((l+r)>>1)int set[maxn<<4];LL sum[maxn<<4];LL add[maxn*10];int x[maxn<<2];void up(int rt,int l,int r){sum[rt]=sum[ls]+sum[rs];}void down(int rt,int l,int r){ if(add[rt]){ sum[ls]+=(LL)((x[mid+1]-x[l])*add[rt]); sum[rs]+=(LL)((x[r+1]-x[mid+1])*add[rt]); add[ls]+=add[rt]; add[rs]+=add[rt]; add[rt]=0; }}void ins(int rt,int l,int r,int L,int R){ if(L<=l&&r<=R){ sum[rt]+=(LL)(x[r+1]-x[l]); add[rt]++; return ; } down(rt,l,r); if(L<=mid)ins(ls,l,mid,L,R); if(mid<R)ins(rs,mid+1,r,L,R); up(rt,l,r);}LL query(int rt,int l,int r,int L,int R){ // printf("%d %d %d\n",l,r,sum[rt]); if(set[rt])return 0; if(L<=l&&r<=R){ set[rt]=1; LL tmp=sum[rt]; sum[rt]=0; return tmp; } down(rt,l,r); LL res=0; if(L<=mid)res+=query(ls,l,mid,L,R); if(mid<R)res+=query(rs,mid+1,r,L,R); up(rt,l,r); return res;}int ll[maxn<<1],rr[maxn<<1];int n,m,cnt,tmp;struct line{ int l,r,h; int id; line(int l=0,int r=0,int h=0):l(l),r(r),h(h){}}e[maxn];LL ans[maxn];int cmp(line x,line y){return x.h>y.h;}int main(){ while(~scanf("%d%d",&n,&m)){ memset(set,0,sizeof set); memset(sum,0,sizeof sum); memset(add,0,sizeof add); cnt=0; for(int i=0;i<n;++i){ scanf("%d%d",&ll[i],&rr[i]); x[cnt++]=ll[i];x[cnt++]=rr[i]; } for(int i=0;i<m;++i){ scanf("%d%d%d",&e[i].l,&e[i].r,&e[i].h); x[cnt++]=e[i].l;x[cnt++]=e[i].r; e[i].id=i; } sort(x,x+cnt); tmp=(int)(unique(x,x+cnt)-x); sort(e,e+m,cmp); for(int i=0;i<n;++i){ ll[i]=(int)(lower_bound(x,x+tmp,ll[i])-x); rr[i]=(int)(lower_bound(x,x+tmp,rr[i])-x)-1; ins(1,0,tmp-1,ll[i],rr[i]); } for(int i=0;i<m;++i){ e[i].l=(int)(lower_bound(x,x+tmp,e[i].l)-x); e[i].r=(int)(lower_bound(x,x+tmp,e[i].r)-x)-1; ans[e[i].id]=query(1,0,tmp-1,e[i].l,e[i].r); } for(int i=0;i<m;++i)printf("%lld\n",ans[i]); printf("\n"); } return 0;}
0 0
- zoj 3299 线段树
- ZOJ 3299 线段树
- zoj 3299 线段树 离散化
- 【ZOJ】3299 Fall the Brick 线段树
- ZOJ 3299 Fall the Brick (线段树)
- zoj 1610 线段树
- zoj 1610 线段树
- zoj 3635 线段树
- zoj 3724 线段树
- ZOJ 3686 线段树
- ZOJ 3635 线段树
- ZOJ 3635 线段树
- 线段树 ZOJ 3574
- ZOJ 3772 线段树
- ZOJ 1610 线段树
- zoj 1610 线段树
- ZOJ 3324 Machine(线段树)
- zoj 3540 线段树笔记
- 如何调用需要指向包含字符串的结构的指针的非托管函数
- 即时通讯——P2P传输技术详解
- 不能打开到主机的连接, 在端口 1521: 连接失败
- Android蓝牙开发(二):相关的API简介
- EXPIRE
- zoj 3299 线段树
- HDU 4859(Bestcoder #1 1003)海岸线(网络流之最小割)
- 针对Android4.0以上屏蔽系统Hemo键
- 《ASP.NET本质论》大文件上传
- POJ 3255 Roadblocks
- OpenCV学习笔记18 OpenCV高级GUI和多媒体模块 HIGHGUI MODULE (二)
- jquery ajax 表单验证
- 申请iOS develop program
- 获取数据库表中数据的insert语句