BZOJ1067: [SCOI2007]降雨量
题解:线段树模板分类讨论题....偶然看见vfk说可以平衡树啊 那就试试平衡树咯 不过讨论到死啊
#include <bits/stdc++.h> const int MAXN=5e4+10; using namespace std; int pre[MAXN],maxn[MAXN],ch[MAXN][2],size[MAXN],rt,key[MAXN]; int a[MAXN],b[MAXN]; vector<pair<int,int> >vec; int cnt=0,n,m; void newnode(int &x,int y,int vul){ x=++cnt;ch[x][0]=ch[x][1]=0;pre[x]=y; key[x]=maxn[x]=vul;size[x]=1; } void up(int x){ maxn[x]=max(key[x],max(maxn[ch[x][0]],maxn[ch[x][1]])); size[x]=size[ch[x][0]]+size[ch[x][1]]+1; } void rotate(int x,int kind){ int y=pre[x]; ch[y][!kind]=ch[x][kind];pre[ch[x][kind]]=y; if(pre[y])ch[pre[y]][ch[pre[y]][1]==y]=x; pre[x]=pre[y];ch[x][kind]=y;pre[y]=x; up(y);up(x); } void splay(int x,int goal){ while(pre[x]!=goal){ if(pre[pre[x]]==goal)rotate(x,ch[pre[x]][0]==x); else{ int y=pre[x];int kind=ch[pre[y]][0]==y; if(ch[y][kind]==x)rotate(x,!kind),rotate(x,kind); else rotate(y,kind),rotate(x,kind); } } if(goal==0)rt=x; up(x); } void built(int &x,int l,int r,int y){ if(l>r)return ; int mid=(l+r)>>1; newnode(x,y,b[mid]);vec.push_back(make_pair(a[mid],cnt)); built(ch[x][0],l,mid-1,x); built(ch[x][1],mid+1,r,x); up(x); } void inte(){ rt=0;cnt=0; built(rt,1,n,0); } vector<pair<int,int> >::iterator ite,ip; int main(){ scanf("%d",&n); vec.clear(); for(int i=1;i<=n;i++)scanf("%d%d",&a[i],&b[i]); inte(); sort(vec.begin(),vec.end()); scanf("%d",&m);int x,y; for(int i=1;i<=m;i++){ scanf("%d%d",&x,&y); if(x>y){puts("false");continue;} int t1=lower_bound(vec.begin(),vec.end(),make_pair(x,0))-vec.begin(); int t2=lower_bound(vec.begin(),vec.end(),make_pair(y,0))-vec.begin(); if(t1==vec.size()){puts("maybe");continue;} if(t1==t2){puts("maybe");continue;} if(t2==vec.size()){ if(vec[t1].first==x){ splay(vec[t1].second,0); if(key[vec[t1].second]>maxn[ch[rt][1]]){puts("maybe");continue;} else {puts("false");continue;} } else {puts("maybe");continue;} } if(vec[t1].first!=x&&vec[t2].first!=y){puts("maybe");continue;} splay(vec[t1].second,0);splay(vec[t2].second,rt); if(vec[t1].first!=x&&vec[t2].first==y){ if(key[vec[t2].second]>maxn[ch[ch[rt][1]][0]]&&key[vec[t1].second]<key[vec[t2].second]){puts("maybe");continue;} else {puts("false");continue;} } if(vec[t1].first==x&&vec[t2].first!=y){ if(key[vec[t1].second]>maxn[ch[ch[rt][1]][0]]){puts("maybe");continue;} else{puts("false");continue;} } if(key[vec[t2].second]<=maxn[ch[ch[rt][1]][0]]||key[vec[t2].second]>key[vec[t1].second]){puts("false");continue;} else{ int t3=y-x-1; if(size[ch[ch[rt][1]][0]]==t3)puts("true"); else puts("maybe"); continue; } puts("false"); } return 0; }
1067: [SCOI2007]降雨量
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 6471 Solved: 1723
[Submit][Status][Discuss]
Description
我们常常会说这样的话:“X年是自Y年以来降雨量最多的”。它的含义是X年的降雨量不超过Y年,且对于任意
Y<Z<X,Z年的降雨量严格小于X年。例如2002,2003,2004和2005年的降雨量分别为4920,5901,2832和3890,
则可以说“2005年是自2003年以来最多的”,但不能说“2005年是自2002年以来最多的”由于有些年份的降雨量未
知,有的说法是可能正确也可以不正确的。
Input
输入仅一行包含一个正整数n,为已知的数据。以下n行每行两个整数yi和ri,为年份和降雨量,按照年份从小
到大排列,即yi<yi+1。下一行包含一个正整数m,为询问的次数。以下m行每行包含两个数Y和X,即询问“X年是
自Y年以来降雨量最多的。”这句话是必真、必假还是“有可能”。
Output
对于每一个询问,输出true,false或者maybe。
Sample Input
6
2002 4920
2003 5901
2004 2832
2005 3890
2007 5609
2008 3024
5
2002 2005
2003 2005
2002 2007
2003 2007
2005 2008
2002 4920
2003 5901
2004 2832
2005 3890
2007 5609
2008 3024
5
2002 2005
2003 2005
2002 2007
2003 2007
2005 2008
Sample Output
false
true
false
maybe
false
true
false
maybe
false
HINT
100%的数据满足:1<=n<=50000, 1<=m<=10000, -10^9<=yi<=10^9, 1<=ri<=10^9