BZOJ 2501 [usaco2010 Oct]Soda Machine
【题意概述】
给出一个[0,1,000,000,000]的整数数轴,刚开始每个位置都为0,有n个区间加操作,最后询问数轴上最大的数是多少。
【题解】
我写的是离散化后线段树维护区间最值。
其实貌似不用线段树QAQ...
#include<cstdio> #include<algorithm> #define N 400010 #define rg register #define ls (u<<1) #define rs (u<<1|1) #define mid ((a[u].l+a[u].r)>>1) using namespace std; int n,ans,l[N],r[N],b[N]; struct tree{ int l,r,del,mx; }a[N]; inline int read(){ int f=1,k=0; char c=getchar(); while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); return k*f; } inline int max(int a,int b){ return a>b?a:b; } inline void pushup(int u){ a[u].mx=max(a[ls].mx,a[rs].mx); } inline void pushdown(int u){ if(!a[u].del) return; int D=a[u].del; a[u].del=0; a[ls].del+=D; a[ls].mx+=D; a[rs].del+=D; a[rs].mx+=D; } void build(int u,int l,int r){ a[u].l=l; a[u].r=r; a[u].mx=0; if(l<r) build(ls,l,mid),build(rs,mid+1,r); } void add(int u,int l,int r,int d){ if(l<=a[u].l&&a[u].r<=r){ a[u].del+=d; a[u].mx+=d; return; } pushdown(u); if(l<=mid) add(ls,l,r,d); if(r>mid) add(rs,l,r,d); pushup(u); } int query(int u,int l,int r){ if(l<=a[u].l&&a[u].r<=r) return a[u].mx; pushdown(u); int ret=0; if(l<=mid) ret=query(ls,l,r); if(r>mid) ret=max(ret,query(rs,l,r)); return ret; } int main(){ n=read(); for(rg int i=1;i<=n;i++){ l[i]=b[i]=read(); r[i]=b[i+n]=read(); } sort(b+1,b+1+(n<<1)); int n2=unique(b+1,b+1+(n<<1))-b-1; for(rg int i=1;i<=n;i++) l[i]=lower_bound(b+1,b+1+n2,l[i])-b; for(rg int i=1;i<=n;i++) r[i]=lower_bound(b+1,b+1+n2,r[i])-b; // for(rg int i=1;i<=n;i++){ // printf("%d %d\n",l[i],r[i]); // } // printf("n2=%d\n",n2); ans=0; build(1,1,n2); for(rg int i=1;i<=n;i++){ add(1,l[i],r[i],1); } for(rg int i=1;i<=n2;i++){ ans=max(ans,query(1,i,i)); //printf("%d\n",query(1,i,i)); } printf("%d\n",ans); return 0; }