[BZOJ1067][SCOI2007]降雨量(线段树)
来源:互联网 发布:java 图形界面案例 编辑:程序博客网 时间:2024/05/22 19:26
题目描述
传送门
题解
离线离散化, 声明的年份和查找的年份一起建线段树。
线段树维护一下区间最大值,两个点之间是否有没有声明的年份打标记。
判断比较吃屎。
我大的分了两种情况:一个是需要在线段树中查询的,一个是直接判断的。
查询了之后,有好几种情况,分别按照是否出现、权值还有中间是否有相隔的年份来判断。
代码
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<map>using namespace std;const int max_n=1e5+5;const int max_tree=max_n*5;const int INF=1e9;struct hp{ int Maxn,Flag;};struct hq{ int year,val; bool flag;}a[max_n];struct ho{ int x,y;}ask[max_n];int n,m,N,x,y,lrange,rrange;int year[max_n],val[max_n];bool flag[max_n];int maxn[max_tree],delta[max_tree];map <int,int> hash;map <int,bool> pd;inline int in(){ int x=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9'){ if (ch=='-') f=-1; ch=getchar(); } while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f;}inline int cmp(hq a,hq b){ return a.year<b.year||(a.year==b.year&&a.val>b.val)||(a.year==b.year&&a.val==b.val&&a.flag>b.flag);}inline void update(int now){ maxn[now]=max(maxn[now<<1],maxn[now<<1|1]); delta[now]=delta[now<<1]&&delta[now<<1|1];}inline void build(int now,int l,int r){ int mid=(l+r)>>1; if (l==r){ maxn[now]=val[l]; delta[now]=flag[l]; return; } build(now<<1,l,mid); build(now<<1|1,mid+1,r); update(now);}inline hp query(int now,int l,int r,int lrange,int rrange){ hp ans; int mid=(l+r)>>1; int MAXN=0; bool FLAG=true; if (lrange<=l&&r<=rrange) return ans=(hp){maxn[now],delta[now]}; if (lrange<=mid){ ans=query(now<<1,l,mid,lrange,rrange); MAXN=max(MAXN,ans.Maxn); FLAG=FLAG&&ans.Flag; } if (mid+1<=rrange){ ans=query(now<<1|1,mid+1,r,lrange,rrange); MAXN=max(MAXN,ans.Maxn); FLAG=FLAG&&ans.Flag; } return ans=(hp){MAXN,FLAG}; }int main(){ n=in(); a[0].year=-INF; for (int i=1;i<=n;++i){ a[i].year=in()+INF; a[i].val=in(); pd[a[i].year]=true; if (a[i].year==a[i-1].year+1) a[i].flag=true; else a[i].flag=false; } m=in(); for (int i=1;i<=m;++i){ ask[i].y=in()+INF; ask[i].x=in()+INF; a[++n].year=ask[i].y; a[n].val=a[n].flag=0; a[++n].year=ask[i].x; a[n].val=a[n].flag=0; } sort(a+1,a+n+1,cmp); for (int i=1;i<=n;++i) if (a[i].year!=a[i-1].year){ hash[a[i].year]=++N; val[N]=a[i].val; flag[N]=a[i].flag; } build(1,1,N); for (int i=1;i<=m;++i){ y=ask[i].y; x=ask[i].x; lrange=hash[y]; rrange=hash[x]; bool pd1=pd[y],pd2=pd[x]; if (lrange>rrange){ printf("false\n"); continue; } if (lrange==rrange){ if (pd1) printf("true\n"); else printf("maybe\n"); continue; } if (lrange+1==rrange){ if (!pd1&&!pd2) printf("maybe\n"); else if (!pd1||!pd2) printf("maybe\n"); else{ if (val[lrange]<val[rrange]) printf("false\n"); else{ if (y+1==x) printf("true\n"); else printf("maybe\n"); } } continue; } hp ans=query(1,1,N,lrange+1,rrange-1); if (!pd1&&!pd2){ printf("maybe\n"); continue; } if (!pd1){ if (ans.Maxn>=val[rrange]) printf("false\n"); else printf("maybe\n"); continue; } if (!pd2){ if (ans.Maxn>=val[lrange]) printf("false\n"); else printf("maybe\n"); continue; } if (val[lrange]<val[rrange]) printf("false\n"); else if (ans.Maxn>=val[rrange]) printf("false\n"); else{ if (!(ans.Flag&&flag[rrange])) printf("maybe\n"); else printf("true\n"); } }}
总结
手残脑残毁一生。。。
0 0
- [BZOJ1067][SCOI2007]降雨量(线段树)
- bzoj1067 [SCOI2007]降雨量 (线段树)
- 【bzoj1067】【SCOI2007】【降雨量】【线段树+分类讨论】
- BZOJ1067: [SCOI2007]降雨量 (RMQ或者线段树)
- 【BZOJ1067】【POJ2637】WorstWeather Ever【SCOI2007】降雨量 线段树+恶心讨论
- 【SCOI2007】【BZOJ1067】【codevs2439】降雨量,分类讨论の线段树
- BZOJ1067 [SCOI2007]降雨量 模拟/线段树/map经验书
- bzoj1067: [SCOI2007]降雨量
- 【SCOI2007】【BZOJ1067】降雨量
- [BZOJ1067][SCOI2007]降雨量
- 【bzoj1067】[SCOI2007]降雨量
- 【bzoj1067】[SCOI2007]降雨量
- BZOJ1067[SCOI2007]降雨量
- 【bzoj1067】[SCOI2007]降雨量 (RMQ)
- BZOJ1067 [SCOI2007]降雨量
- BZOJ1067(SCOI2007)[降雨量]--RMQ
- bzoj1067 scoi2007 降雨量 RMQ+讨论
- BZOJ1067 [SCOI2007]降雨量 RMQ+乱搞
- LeetCodet题解--12. Integer to Roman
- CodeForces 560CGerald's Hexagon(几何)
- 三言两语说shader(六)外发光、表面shader
- JavaWeb - 知识点
- 第六周项目三 IP地址类
- [BZOJ1067][SCOI2007]降雨量(线段树)
- ZOJ 2836Number Puzzle(容斥原理)
- Tsinsen A1106 数制转换
- 慕司名称的由来
- 一点吐槽
- Android学习笔记之控件架构
- hao—C++和Java从编译到运行的过程区别
- HashMap的容量与扩容
- 持续集成篇_08_Hudson持续集成服务器的使用(远程自动化部署)