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

浙公网安备 33010602011771号