hdu5861 Road【线段树】
来源:互联网 发布:怎么申请淘宝主播 编辑:程序博客网 时间:2024/06/05 08:43
多校那么多道线段树就没有一道在比赛时写出来的。
根据题意,每一条公路只能开一次。所以对于每一条公路,第一开了之后,只有当最后一次使用完成之后才可以关闭。所以,我们要预处理出每条公路第一次使用和最后一次使用的时间。这里我直接用线段树维护每一条公路的最迟和最早使用时间。之后,本来自己想的是在以天数建一棵线段树,把每一条公路的最早和最迟使用区间内的每一点都更新值,最后在查询得出答案。看了人家的博客后,发现可以在原来的树上直接做,将得到的时间排序,然后最早时间线段树对应点加上费用,最迟时间之后线段树上对应点点减去费用。每一天的答案都在sum[1]上。
#include<bits/stdc++.h>using namespace std;typedef long long ll;const int N=200000+10;struct node{ int x,t,f;} p[4*N];ll sum[4*N+10],a[N];int tot,n,m,mi[4*N+10],ma[4*N+10];int l[N],r[N];int cmp(node n1,node n2){ if(n1.t==n2.t) return n1.f<n2.f; else return n1.t<n2.t;}void down(int o){ if(mi[o]!=-1) { if(mi[o*2]==-1) mi[o*2]=mi[o]; else mi[o*2]=min(mi[o],mi[o*2]); if(mi[o*2+1]==-1) mi[o*2+1]=mi[o]; else mi[o*2+1]=min(mi[o],mi[o*2+1]); } if(ma[o]!=-1) { if(ma[o*2]==-1) ma[o*2]=ma[o]; else ma[o*2]=max(ma[o],ma[o*2]); if(ma[o*2+1]==-1) ma[o*2+1]=ma[o]; else ma[o*2+1]=max(ma[o],ma[o*2+1]); } mi[o]=ma[o]=-1;}void update(int o,int l,int r,int x,int y,int v){ //printf("%d %d\n",l,r); int mid=l+(r-l)/2; if(x<=l&&y>=r) { if(mi[o]==-1) mi[o]=v; else mi[o]=min(mi[o],v); if(ma[o]==-1) ma[o]=v; else ma[o]=max(ma[o],v); } else { down(o); if(x<=mid) update(o*2,l,mid,x,y,v); if(y>mid) update(o*2+1,mid+1,r,x,y,v); if(mi[o*2]==mi[o*2+1]) mi[o]=mi[o*2]; else mi[o]=-1; if(ma[o*2]==ma[o*2+1]) ma[o]=ma[o*2]; else ma[o]=-1; }}void query(int o,int l,int r){ if(l==r) { if(mi[o]!=-1) { node tmp; tmp.x=l; tmp.t=mi[o]; tmp.f=1; p[tot]=tmp; tot++; } if(ma[o]!=-1) { node tmp; tmp.x=l; tmp.t=ma[o]+1; tmp.f=0; p[tot]=tmp; tot++; } //printf(" %lld %lld\n",mi[o],ma[o]); } else { down(o); int mid=l+(r-l)/2; query(o*2,l,mid); query(o*2+1,mid+1,r); }}void updatesum(int o,int l,int r,int x,ll v){ if(l==r) { sum[o]+=v; // printf("%lld\n",sum[o]); } else { int mid=l+(r-l)/2; if(x<=mid) updatesum(o*2,l,mid,x,v); else updatesum(o*2+1,mid+1,r,x,v); sum[o]=sum[o*2]+sum[o*2+1]; }}int main(){ while(~scanf("%d%d",&n,&m)) { for(int i=1; i<n; i++) scanf("%lld",&a[i]); memset(sum,0,sizeof(sum)); memset(ma,0xff,sizeof(ma)); memset(mi,0xff,sizeof(mi)); for(int i=1; i<=m; i++) { scanf("%d%d",&l[i],&r[i]); if(l[i]>r[i]) swap(l[i],r[i]); r[i]--; update(1,1,n-1,l[i],r[i],i); } tot=0; query(1,1,n-1); sort(p,p+tot,cmp); //printf("%d\n",tot); int j=0; for(int i=1; i<=m; i++) { while(p[j].t==i) { if(p[j].f==0) updatesum(1,1,n-1,p[j].x,-a[p[j].x]); else updatesum(1,1,n-1,p[j].x,a[p[j].x]); j++; if(j>=tot) break; } printf("%lld\n",sum[1]); } } return 0;}
0 0
- hdu5861 Road【线段树】
- hdu5861 Road,线段树,然后扫描
- hdu5861 Road(线段树成段更新+优先队)
- hdu5861【线段树】
- HDU5861-Road
- hdu5861 维护最大最小值线段树
- HDU5861(线段树好题)
- HDU5861 (线段树区间更新+单点查询)
- 线段树 高速公路(road)
- bzoj2752 高速公路(road) 线段树
- HDU 5861 Road(线段树)
- 2016多校训练Contest10: 1005 Road hdu5861
- [TOJ]3243 Blocked Road --线段树
- tju3243 Blocked Road(树状数组/线段树)
- BZOJ 2752 [HAOI2012]高速公路(road) 线段树
- BZOJ 2752 [HAOI2012]高速公路(road)【线段树
- HDU 5861 Road(线段树)
- hdu 5861 Road 线段树区间更新
- Exception:Duplicate id 0x7f0b00d6, tag null, or parent id 0xffffffff with another fragment
- 解析Spring源码(5)--this.documentLoader.loadDocument
- linux内核 路由fib表之创建
- iOS tableView下拉图片变大
- 适配计模式
- hdu5861 Road【线段树】
- windows安装MySQL的非安装压缩包
- ViewPager
- 嵌入式开发第30天(线程池)
- java面向对象前言之final关键字
- [Java并发]Java中Executor框架(四)
- 线性表的顺序储结构
- Android面试精华
- Vijos P1002过河