转载请注明出处谢谢:http://blog.youkuaiyun.com/vmurder/article/details/42918883
题意:自己去BZOJ上看。
但是总之询问就是要求
// 它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小于X年
// 左>=右>中
题解:然后首先离散化一下,然后把确定的年加到线段树中,乱搞一下就过了。
但是,,,讨论太恶心了!!
详情参照代码,写得很清晰(不清晰怎么A这道题)
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 151000
using namespace std;
struct LSH
{
int x,y,id;
//id/2表示询问 ,偶l奇r
bool operator < (const LSH &a)const{return x<a.x;}
}lsh[N];
int n,m;
int ql[N],qr[N];
struct Segment_Tree
{
int l,r,size,x;
}s[N<<2];
int val[N];
inline void pushup(int note)
{
s[note].x=max(s[note<<1].x,s[note<<1|1].x);
s[note].size=s[note<<1].size+s[note<<1|1].size;
}
void build(int note,int l,int r)
{
s[note].l=l,s[note].r=r;
if(l==r)return ;
int mid=l+r>>1;
build(note<<1,l,mid),build(note<<1|1,mid+1,r);
}
inline void add(int note,int pos,int x)
{
if(s[note].l==s[note].r)
{
s[note].size=1;
s[note].x=x;
val[pos]=x;
return ;
}
int mid=s[note].l+s[note].r>>1;
if(pos<=mid)add(note<<1,pos,x);
else add(note<<1|1,pos,x);
pushup(note);
}
inline int query(int note,int l,int r,int &ans)
{
if(s[note].l==l&&r==s[note].r)
{
ans=max(ans,s[note].x);
return s[note].size;
}
int mid=s[note].l+s[note].r>>1;
if(r<=mid)return query(note<<1,l,r,ans);
else if(l>mid)return query(note<<1|1,l,r,ans);
else return query(note<<1,l,mid,ans)+query(note<<1|1,mid+1,r,ans);
}
int main()
{
freopen("test.in","r",stdin);
int i,j,k;
for(scanf("%d",&n),i=1;i<=n;i++)scanf("%d%d",&lsh[i].x,&lsh[i].y);
for(scanf("%d",&m),i=1;i<=m;i++)
{
scanf("%d%d",&lsh[n+i*2-1].x,&lsh[n+i*2]);
lsh[n+i*2-1].id=i*2,lsh[n+i*2].id=i*2+1;
}n+=m*2;
sort(lsh+1,lsh+n+1);
int dis,now=0;
for(i=1;i<=n;i++)
{
dis=lsh[i].x-lsh[i-1].x;
if(dis==1)now++;
else if(dis>1) now+=2;
else if(i==1)now++;
if(lsh[i].id)
{
if(lsh[i].id&1)qr[lsh[i].id>>1]=now;
else ql[lsh[i].id>>1]=now;
lsh[i].id=0;
}
else lsh[i].id=now;
}
build(1,1,now);
for(i=1;i<=n;i++)if(lsh[i].id)
add(1,lsh[i].id,lsh[i].y);
int ans,flag;
for(i=1;i<=m;i++)
{// 它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小于X年
// 左>=右>中
int size=0,vll=val[ql[i]],vrl=val[qr[i]];
if(qr[i]-ql[i]>1){
size=query(1,ql[i]+1,qr[i]-1,ans=0);
flag=(size==qr[i]-ql[i]-1);
// 两个都没赋值
if(vll==0&&vrl==0)
{
// 只能是maybe,因为这个随便调。
puts("maybe");
}
//左没值,右有值
else if(vll==0&&vrl)
{
// r>mid 才可能满足条件
if(flag||flag==0){
if(vrl>ans)puts("maybe");
else puts("false");
}
/* else {
if(vrl>ans)puts("maybe"); // 即使mid不确定,但是至少有个最小值
else puts("false"); // 下面一大组情况同此
}*/
}
//左有值,右没值
else if(vll&&vrl==0)
{
// l>=r>mid r的取值可能很乱
// 所以至少需要l>mid
if(flag||flag==0){ // 这个判断条件有点厉害,思想上是这样,
// 但是可以省掉的。
if(vll>ans)puts("maybe");
else puts("false");
}
}
// 两个都赋值了,那么 l>=r>mid。
else {
// l>=r>mid
if(flag){
if(vll>=vrl&&vrl>ans)puts("true");
else puts("false");
}
else {
if(vll>=vrl&&vrl>ans)puts("maybe"); // 命,自有天定
else puts("false");// 然,不争则必折也。
}
}
}
else {
if(vll&&vrl)
{
if(vrl<=vll)puts("true");
else puts("false");
}
else puts("maybe");
}
}
return 0;
}
POJ代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 151000
using namespace std;
struct LSH
{
int x,y,id;
//id/2表示询问 ,偶l奇r
bool operator < (const LSH &a)const{return x<a.x;}
}lsh[N];
int n,m;
int ql[N],qr[N];
struct Segment_Tree
{
int l,r,size,x;
}s[N<<2];
int val[N];
void init()
{
memset(s,0,sizeof s);
memset(val,0,sizeof val);
memset(lsh,0,sizeof lsh);
}
inline void pushup(int note)
{
s[note].x=max(s[note<<1].x,s[note<<1|1].x);
s[note].size=s[note<<1].size+s[note<<1|1].size;
}
void build(int note,int l,int r)
{
s[note].l=l,s[note].r=r;
if(l==r)return ;
int mid=l+r>>1;
build(note<<1,l,mid),build(note<<1|1,mid+1,r);
}
inline void add(int note,int pos,int x)
{
if(s[note].l==s[note].r)
{
s[note].size=1;
s[note].x=x;
val[pos]=x;
return ;
}
int mid=s[note].l+s[note].r>>1;
if(pos<=mid)add(note<<1,pos,x);
else add(note<<1|1,pos,x);
pushup(note);
}
inline int query(int note,int l,int r,int &ans)
{
if(s[note].l==l&&r==s[note].r)
{
ans=max(ans,s[note].x);
return s[note].size;
}
int mid=s[note].l+s[note].r>>1;
if(r<=mid)return query(note<<1,l,r,ans);
else if(l>mid)return query(note<<1|1,l,r,ans);
else return query(note<<1,l,mid,ans)+query(note<<1|1,mid+1,r,ans);
}
int main()
{
int i,j,k;
while(1)
{
init();
for(scanf("%d",&n),i=1;i<=n;i++)scanf("%d%d",&lsh[i].x,&lsh[i].y);
for(scanf("%d",&m),i=1;i<=m;i++)
{
scanf("%d%d",&lsh[n+i*2-1].x,&lsh[n+i*2]);
lsh[n+i*2-1].id=i*2,lsh[n+i*2].id=i*2+1;
}n+=m*2;
if(n==0)return 0;
sort(lsh+1,lsh+n+1);
int dis,now=0;
for(i=1;i<=n;i++)
{
dis=lsh[i].x-lsh[i-1].x;
if(dis==1)now++;
else if(dis>1) now+=2;
else if(i==1)now++;
if(lsh[i].id)
{
if(lsh[i].id&1)qr[lsh[i].id>>1]=now;
else ql[lsh[i].id>>1]=now;
lsh[i].id=0;
}
else lsh[i].id=now;
}
build(1,1,now);
for(i=1;i<=n;i++)if(lsh[i].id)
add(1,lsh[i].id,lsh[i].y);
int ans,flag;
for(i=1;i<=m;i++)
{// 它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小于X年
// 左>=右>中
int size=0,vll=val[ql[i]],vrl=val[qr[i]];
if(qr[i]-ql[i]>1){
size=query(1,ql[i]+1,qr[i]-1,ans=0);
flag=(size==qr[i]-ql[i]-1);
// 两个都没赋值
if(vll==0&&vrl==0)
{
// 只能是maybe,因为这个随便调。
puts("maybe");
}
//左没值,右有值
else if(vll==0&&vrl)
{
// r>mid 才可能满足条件
if(flag||flag==0){
if(vrl>ans)puts("maybe");
else puts("false");
}
/* else {
if(vrl>ans)puts("maybe"); // 即使mid不确定,但是至少有个最小值
else puts("false"); // 下面一大组情况同此
}*/
}
//左有值,右没值
else if(vll&&vrl==0)
{
// l>=r>mid r的取值可能很乱
// 所以至少需要l>mid
if(flag||flag==0){ // 这个判断条件有点厉害,思想上是这样,
// 但是可以省掉的。
if(vll>ans)puts("maybe");
else puts("false");
}
}
// 两个都赋值了,那么 l>=r>mid。
else {
// l>=r>mid
if(flag){
if(vll>=vrl&&vrl>ans)puts("true");
else puts("false");
}
else {
if(vll>=vrl&&vrl>ans)puts("maybe"); // 命,自有天定
else puts("false");// 然,不争则必折也。
}
}
}
else {
if(vll&&vrl)
{
if(vrl<=vll)puts("true");
else puts("false");
}
else puts("maybe");
}
}
puts("");
}
return 0;
}