BZOJ1067 [SCOI2007]降雨量 模拟/线段树/map经验书
从知道x,y能是没出现过的我就知道GG了
之前写的版本耦合太强,完全改不过来只好推掉重写。。
学到了max_element以及map的一些坑
map的lower_bound熟练度++
#include<iostream> #include<stdio.h> #include<algorithm> #include<queue> #include<string.h> #include<math.h> #include<set> #include<map> #include<vector> #include<iomanip> #include<stack> using namespace std; #define ll long long #define ull unsigned long long #define pb push_back #define mem(a) memset(a,0,sizeof a) #define FOR(a) for(int i=1;i<=a;i++) #define sqr(a) (a)*(a) const int maxn=5e4+7; const int inf=0x3f3f3f3f; int n,q; int tot; struct dot{ int y,r,id;; }arr[maxn]; int a[maxn]; //id -> 降雨量 map<int,int>b; //年份 -> id struct NODE{ bool unk; int mx; }ST[maxn<<2]; void pushup(int rt){ ST[rt].unk=(ST[rt<<1].unk | ST[rt<<1|1].unk); ST[rt].mx=max(ST[rt<<1].mx,ST[rt<<1|1].mx); } void build(int l,int r,int rt){ if(l==r){ if(a[l]==0){ST[rt].unk=1;ST[rt].mx=-inf;} else{ST[rt].unk=0;ST[rt].mx=a[l];} return; } int m=l+r>>1;build(l,m,rt<<1);build(m+1,r,rt<<1|1);pushup(rt); } int queryMX(int a,int b,int l,int r,int rt){ if(a<=l&&b>=r){return ST[rt].mx;} int ans=-inf; int m=l+r>>1; if(a<=m)ans=queryMX(a,b,l,m,rt<<1); if(b>m)ans=max(ans,queryMX(a,b,m+1,r,rt<<1|1)); return ans; } bool queryUN(int a,int b,int l,int r,int rt){ if(a<=l&&b>=r){return ST[rt].unk;} int m=l+r>>1; if(a<=m)if(queryUN(a,b,l,m,rt<<1))return true; if(b>m)if(queryUN(a,b,m+1,r,rt<<1|1))return true; return false; } int maxY=-inf,minY=inf; int work(int x,int y){ // y是x之后降雨最高 bool havx=b.count(x),havy=b.count(y); //cout<<havx<<" "<<havy<<endl; map<int,int>::iterator lwbx=b.lower_bound(x); map<int,int>::iterator higx=b.upper_bound(x); map<int,int>::iterator lwby=b.lower_bound(y); map<int,int>::iterator higy=b.upper_bound(y); lwbx--;map<int,int>::iterator lesx=lwbx;lwbx++; lwby--;map<int,int>::iterator lesy=lwby;lwby++; int idx=b[x],idy=b[y]; if(!havx && !havy)return 3; if(havy && havx){ if( a[idx]>=a[idy] &&( idx+1==idy || (a[idy]>queryMX(idx+1,idy-1,1,tot,1) && !queryUN(idx+1,idy-1,1,tot,1) ) ) )return 1; if( a[idx]>=a[idy] && a[idy]>queryMX(idx+1,idy-1,1,tot,1) && queryUN(idx+1,idy-1,1,tot,1) )return 3; return 2; } //x,y其一出现 if(havx){ //!havy if(higx == lwby){return 3;} if(idx==tot)return 3; if(lwby==b.end()){ if(queryMX(idx+1,b[maxY],1,tot,1) < a[idx])return 3; else return 2; }else{ if(queryMX(idx+1,lesy->second,1,tot,1) < a[idx])return 3; else return 2; } } if(havy){ if(higx == lwby){return 3;} if(b[y]==1)return 3; if(queryMX(higx->second,idy-1,1,tot,1) < a[idy])return 3; else return 2; } } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){scanf("%d%d",&arr[i].y,&arr[i].r);} arr[1].id=1; b[arr[1].y]=1; a[1]=arr[1].r; for(int i=2;i<=n;i++){ if(arr[i].y-arr[i-1].y>1){ arr[i].id=arr[i-1].id+2; a[arr[i].id]=arr[i].r; b[arr[i].y]=arr[i].id; } else { arr[i].id=arr[i-1].id+1; a[arr[i].id]=arr[i].r; b[arr[i].y]=arr[i].id; } } maxY=max_element(b.begin(),b.end())->first; minY=min_element(b.begin(),b.end())->first; tot=arr[n].id; build(1,tot,1); scanf("%d",&q); while(q--){ int x,y;scanf("%d%d",&x,&y); bool misx=b.count(x),misy=b.count(y); if(y<x){puts("false");continue;} int flag=work(x,y); if(flag==1)puts("true"); else if(flag==2)puts("false"); else puts("maybe"); if(!misx)b.erase(x); if(!misy)b.erase(y); } }