1. 程式人生 > >bzoj 1067: [SCOI2007]降雨量 (離散化+線段樹)

bzoj 1067: [SCOI2007]降雨量 (離散化+線段樹)

https ace esp problem define clas else line unique

鏈接:https://www.lydsy.com/JudgeOnline/problem.php?id=1067

思路: 毒瘤題,寫的自閉,改了一晚上,註意要理清題目的邏輯 x小於等於y,x,y之間的數嚴格小於x,不能等於;

分類討論懶得寫的,很簡單的分類討論。

實現代碼:

#include<bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mid int m = (l + r) >> 1
const
int M = 1e5+10; const int inf = 0x3f3f3f3f; int vis[M]; int num[M<<2],sum[M<<2],x1[M],x2[M],yy[M],y2[M],cnt,a[M<<2]; void pushup(int rt){ sum[rt] = max(sum[rt<<1],sum[rt<<1|1]); num[rt] = num[rt<<1] + num[rt<<1|1]; } void update(int p,int c,int
l,int r,int rt){ if(l == r){ sum[rt] = c; num[rt] = 1; return ; } mid; if(p <= m) update(p,c,lson); else update(p,c,rson); pushup(rt); } int query(int L,int R,int l,int r,int rt){ if(L <= l&&R >= r){ return
sum[rt]; } mid; int ret = -inf; if(L <= m) ret = max(ret,query(L,R,lson)); if(R > m) ret = max(ret,query(L,R,rson)); return ret; } int ask(int L,int R,int l,int r,int rt){ if(L <= l&&R >= r){ return num[rt]; } mid; int ret = 0; if(L <= m) ret += ask(L,R,lson); if(R > m) ret += ask(L,R,rson); return ret; } int main() { int n,x,y,m; scanf("%d",&n); int cnt = 0; for(int i = 1;i <= n;i ++){ scanf("%d%d",&x1[i],&yy[i]); a[++cnt] = x1[i]; } scanf("%d",&m); for(int i = 1;i <= m;i ++){ scanf("%d%d",&x2[i],&y2[i]); a[++cnt] = x2[i]; a[++cnt] = y2[i]; } sort(a+1,a+1+cnt); int nn = unique(a+1,a+1+cnt)-(a+1); for(int i = 1;i <= n;i ++){ x = lower_bound(a+1,a+nn+1,x1[i]) - a; vis[x] = yy[i]; update(x,yy[i],1,nn,1); } for(int i = 1;i <= m;i ++){ x = lower_bound(a+1,a+nn+1,x2[i]) - a; y = lower_bound(a+1,a+nn+1,y2[i]) - a; if(x > y){ printf("false\n"); continue; } if(!vis[x]&&!vis[y]) printf("maybe\n"); else if(vis[x]&&vis[y]){ int cnt = query(x+1,y-1,1,nn,1); int flag = ask(x,y,1,nn,1); if(cnt<vis[y]&&vis[y]<=vis[x]){ if(flag == y2[i]-x2[i]+1) printf("true\n"); else printf("maybe\n"); } else printf("false\n"); } else if(!vis[x]&&vis[y]){ int cnt = query(x,y-1,1,nn,1); if(cnt >= vis[y]) printf("false\n"); else printf("maybe\n"); } else{ int cnt = query(x+1,y,1,nn,1); if(cnt >= vis[x]) printf("false\n"); else printf("maybe\n"); } } return 0; }

bzoj 1067: [SCOI2007]降雨量 (離散化+線段樹)