转载请注明出处谢谢:http://blog.csdn.net/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; }