[luogu2471][SCOI2007]降雨量
阿新 • • 發佈:2018-12-12
細節題……
首先離散化。
然後用線段樹維護最大值
因為左端點和右端點的存在性,要做一系列的討論。
#include <cstdio> #include <cstring> #include <algorithm> #define MAXN 50005 struct Node { int year,val; }G[MAXN]; int N,M; bool cmp(Node a,Node b) {return a.year<b.year;} struct disc { void work() { std::sort(G+1,G+N+1,cmp); } int num(int x,int opt) { int l = 1,r = N; while(l<r) { int mid = (l+r)>>1; if(G[mid].year>=x) r = mid; else l = mid + 1; } if(opt==2&&G[l].year!=x) return l-1; return l; } }d; #define lson (rt<<1) #define rson (rt<<1|1) #define mid ((l+r)>>1) int seg[MAXN<<2]; inline void pushup(int rt) { seg[rt] = std::max(seg[lson],seg[rson]); } void Build(int rt,int l,int r) { if(l==r) { seg[rt] = G[l].val; return; } Build(lson,l,mid); Build(rson,mid+1,r); pushup(rt); } int query(int L,int R,int rt,int l,int r) { if(L>r||R<l||L>R) return 0; if(L<=l&&R>=r) return seg[rt]; int ans = 0; if(L<=mid) ans = query(L,R,lson,l,mid); if(R>mid) ans = std::max(ans,query(L,R,rson,mid+1,r)); return ans; } int main() { scanf("%d",&N); for(int i=1;i<=N;++i) scanf("%d%d",&G[i].year,&G[i].val); d.work(); Build(1,1,N); int x,y; scanf("%d",&M); for(int i=1;i<=M;++i) { scanf("%d%d",&x,&y); int l = d.num(x,1),r = d.num(y,2); int t1 = query(l,l,1,1,N); int t3 = query(r,r,1,1,N); bool f1 = false,f2 = false; if(G[l].year==x) ++l,f1 = true; if(G[r].year==y) --r,f2 = true; int t2 = query(l,r,1,1,N); if(f1) --l; if(f2) ++r; if(x==y) puts("true"); else if(G[l].year!=x&&G[r].year!=y) puts("maybe"); else if(G[l].year!=x) { if(x==y-1) puts("maybe"); else { if(t2>=t3) puts("false"); else puts("maybe"); } } else if(G[r].year!=y) { if(x==y-1) puts("maybe"); else { if(t2>=t1) puts("false"); else puts("maybe"); } } else { if(t3>t1) puts("false"); else if(l==r-1) { if(x==y-1) puts("true"); else puts("maybe"); } else { if(t2>=t3) puts("false"); else if(r-l==y-x) puts("true"); else puts("maybe"); } } } return 0; }