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 MB
Submit: 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

Sample Output

false
true
false
maybe
false

HINT

100%的数据满足:1<=n<=50000, 1<=m<=10000, -10^9<=yi<=10^9, 1<=ri<=10^9

posted @ 2018-08-06 18:57  wang9897  阅读(109)  评论(0编辑  收藏  举报