1. 程式人生 > >bzoj 1645: [Usaco2007 Open]City Horizon 城市地平線【線段樹+hash】

bzoj 1645: [Usaco2007 Open]City Horizon 城市地平線【線段樹+hash】

ash 離散化 hash pan != 題目 getchar() cit names

bzoj題面什麽鬼啊……
題目大意:有一個初始值均為0的數列,n次操作,每次將數列(ai,bi-1)這個區間中的數與ci取max,問n次後元素和
離散化,然後建立線段樹,每次修改在區間上打max標記即可

#include<iostream>
#include<cstdio>
#include<map>
#include<algorithm>
using namespace std;
const int N=100005;
int n,g[N],tot,a[N],b[N],c[N],has,h[N];
map<int,int>mp;
struct
qwe { int l,r,mx; }t[N<<2]; int read() { int r=0,f=1; char p=getchar(); while(p>‘9‘||p<‘0‘) { if(p==‘-‘) f=-1; p=getchar(); } while(p>=‘0‘&&p<=‘9‘) { r=r*10+p-48; p=getchar(); } return r*f; } void
build(int ro,int l,int r) { t[ro].l=l,t[ro].r=r; if(l==r) return; int mid=(l+r)>>1; build(ro<<1,l,mid); build(ro<<1|1,mid+1,r); } void pd(int ro) { if(t[ro].mx!=0) { t[ro<<1].mx=max(t[ro<<1].mx,t[ro].mx); t[ro<<1
|1].mx=max(t[ro<<1|1].mx,t[ro].mx); } } void update(int ro,int l,int r,int v) { if(l>r) return; if(t[ro].l==l&&t[ro].r==r) { t[ro].mx=max(t[ro].mx,v); return; } pd(ro); int mid=(t[ro].l+t[ro].r)>>1; if(r<=mid) update(ro<<1,l,r,v); else if(l>mid) update(ro<<1|1,l,r,v); else update(ro<<1,l,mid,v),update(ro<<1|1,mid+1,r,v); } int ques(int ro,int p) { if(t[ro].l==t[ro].r) return t[ro].mx; pd(ro); int mid=(t[ro].l+t[ro].r)>>1; if(p<=mid) return ques(ro<<1,p); else return ques(ro<<1|1,p); } int main() { n=read(); for(int i=1;i<=n;i++) a[i]=read(),b[i]=read(),c[i]=read(),g[++tot]=a[i],g[++tot]=b[i]; sort(g+1,g+1+tot); for(int i=1;i<=tot;i++) if(i==1||g[i]!=g[i-1]) mp[g[i]]=++has,h[has]=g[i]; build(1,1,has); for(int i=1;i<=n;i++) update(1,mp[a[i]]+1,mp[b[i]],c[i]); long long ans=0; for(int i=2;i<=has;i++) { int nw=ques(1,i); ans+=1ll*nw*(h[i]-h[i-1]); } printf("%lld\n",ans); return 0; }

bzoj 1645: [Usaco2007 Open]City Horizon 城市地平線【線段樹+hash】