bzoj 1067 降雨量
题目大意:
X年是自Y年以来降雨量最多的”。它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小于X年
如2002,2003,2004和2005年的降雨量分别为4920,5901,2832和3890
则可以说“2005年是自2003年以来最多的”
但不能说“2005年是自2002年以来最多的”由于有些年份的降雨量未知,有的说法是可能正确也可以不正确的
思路:
忘了发这道神题的博客
讨论的东西巨多
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstdlib> 6 #include<cstring> 7 #include<vector> 8 #include<queue> 9 #define ll long long 10 #define MAXN 50101 11 #define inf 2147483611 12 using namespace std; 13 int read() 14 { 15 int x=0,f=1; 16 char ch=getchar(); 17 while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();} 18 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 19 return x*f; 20 } 21 struct data 22 { 23 int l,r,maxn; 24 bool mark; 25 }tr[MAXN*5]; 26 int n,t,maxy,miny; 27 void build(int k,int l,int r) 28 { 29 if(l==r) {tr[k].l=tr[k].r=read();miny=min(miny,tr[k].l);maxy=max(maxy,tr[k].l);tr[k].maxn=read();tr[k].mark=1;return ;} 30 tr[k].l=l,tr[k].r=r; 31 int m=(l+r)>>1; 32 build(k<<1,l,m);build(k<<1|1,m+1,r); 33 if(tr[k<<1].mark&&tr[k<<1|1].mark) tr[k].mark=1; 34 if(tr[k<<1].r+1!=tr[k<<1|1].l) tr[k].mark=0; 35 tr[k].l=tr[k<<1].l,tr[k].r=tr[k<<1|1].r; 36 tr[k].maxn=max(tr[k<<1].maxn,tr[k<<1|1].maxn); 37 } 38 int find(int k,int x) 39 { 40 int l=tr[k].l,r=tr[k].r; 41 if(l==r) 42 { 43 if(tr[k].l==x) return tr[k].maxn; 44 else return 0; 45 } 46 if(x<=tr[k<<1].r) return find(k<<1,x); 47 else if(x>=tr[k<<1|1].l) return find(k<<1|1,x); 48 return 0; 49 } 50 bool known(int k,int a,int b) 51 { 52 int l=tr[k].l,r=tr[k].r; 53 //cout<<" known:"<<k<<" l:"<<l<<" r:"<<r<<" maxn:"<<tr[k].maxn<<" mark:"<<tr[k].mark<<" a:"<<a<<" b:"<<b<<endl; 54 if(l==a&&r==b) return tr[k].mark; 55 if(a>=tr[k<<1|1].l) return known(k<<1|1,a,b); 56 else if(b<=tr[k<<1].r) return known(k<<1,a,b); 57 else if(tr[k<<1].r+1!=tr[k<<1|1].l) return false; 58 else return (known(k<<1,a,tr[k<<1].r)&&known(k<<1|1,tr[k<<1|1].l,b)); 59 } 60 int query(int k,int a,int b) 61 { 62 int l=tr[k].l,r=tr[k].r; 63 //cout<<" query:"<<k<<" l:"<<l<<" r:"<<r<<" maxn:"<<tr[k].maxn<<" mark:"<<tr[k].mark<<" a:"<<a<<" b:"<<b<<endl; 64 if(l==a&&r==b) return tr[k].maxn; 65 if(a>=tr[k<<1|1].l) return query(k<<1|1,a,b); 66 else if(b<=tr[k<<1].r) return query(k<<1,a,b); 67 else return max(query(k<<1,a,tr[k<<1].r),query(k<<1|1,tr[k<<1|1].l,b)); 68 } 69 int a_find(int k,int x) 70 { 71 int l=tr[k].l,r=tr[k].r; 72 if(l==r) return tr[k].l; 73 if(x<tr[k<<1].r) return a_find(k<<1,x); 74 else return a_find(k<<1|1,x); 75 } 76 int b_find(int k,int x) 77 { 78 int l=tr[k].l,r=tr[k].r; 79 if(l==r) return tr[k].l; 80 if(x>tr[k<<1|1].l) return b_find(k<<1|1,x); 81 else return b_find(k<<1,x); 82 } 83 int main() 84 { 85 n=read(); 86 maxy=-inf;miny=inf; 87 build(1,1,n); 88 t=read(); 89 int x,y; 90 while(t--) 91 { 92 x=read(),y=read(); 93 if((y>maxy&&x==maxy)||(x<miny&&y==miny)) {printf("maybe\n");continue;} 94 int numx=find(1,x),numy=find(1,y); 95 if(!numx&&!numy) {printf("maybe\n");continue;} 96 int hx=a_find(1,x),hy=b_find(1,y); 97 if(!numx) 98 { 99 if(hx>hy) {printf("maybe\n");continue;} 100 if(query(1,hx,hy)<numy) printf("maybe\n"); 101 else printf("false\n"); 102 } 103 if(!numy) 104 { 105 if(hx>hy) {printf("maybe\n");continue;} 106 if(query(1,hx,hy)<numx) printf("maybe\n"); 107 else printf("false\n"); 108 } 109 if(numx&&numy) 110 { 111 if(numx<numy) {printf("false\n");continue;} 112 if(hx>hy) {if(x==y-1) printf("true\n");else printf("maybe\n");continue;} 113 int k=query(1,hx,hy); 114 if(k>=numy) {printf("false\n");continue;} 115 bool ok=known(1,hx,hy); 116 if(ok&&hx==x+1&&hy==y-1) ok=1; 117 else ok=0; 118 if(ok) {printf("true\n");continue;} 119 else {printf("maybe\n");continue;} 120 printf("false\n"); 121 } 122 } 123 }