[SCOI2007]降雨量
来源:互联网 发布:qq群的淘宝客都是团队 编辑:程序博客网 时间:2024/05/29 17:57
题目描述
我们常常会说这样的话:“X年是自Y年以来降雨量最多的”。它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小于X年。例如2002,2003,2004和2005年的降雨量分别为4920,5901,2832和3890,则可以说“2005年是自2003年以来最多的”,但不能说“2005年是自2002年以来最多的”由于有些年份的降雨量未知,有的说法是可能正确也可以不正确的。
输入输出格式
输入格式:
输入仅一行包含一个正整数n,为已知的数据。以下n行每行两个整数yi和ri,为年份和降雨量,按照年份从小到大排列,即yi<yi+1。下一行包含一个正整数m,为询问的次数。以下m行每行包含两个数Y和X,即询问“X年是自Y年以来降雨量最多的。”这句话是必真、必假还是“有可能”。
输出格式:
对于每一个询问,输出true,false或者maybe。
输入输出样例
输入样例:
6
2002 4920
2003 5901
2004 2832
2005 3890
2007 5609
2008 3024
5
2002 2005
2003 2005
2002 2007
false
true
false
maybe
false
我们常常会说这样的话:“X年是自Y年以来降雨量最多的”。它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小于X年。例如2002,2003,2004和2005年的降雨量分别为4920,5901,2832和3890,则可以说“2005年是自2003年以来最多的”,但不能说“2005年是自2002年以来最多的”由于有些年份的降雨量未知,有的说法是可能正确也可以不正确的。
输入输出格式
输入格式:
输入仅一行包含一个正整数n,为已知的数据。以下n行每行两个整数yi和ri,为年份和降雨量,按照年份从小到大排列,即yi<yi+1。下一行包含一个正整数m,为询问的次数。以下m行每行包含两个数Y和X,即询问“X年是自Y年以来降雨量最多的。”这句话是必真、必假还是“有可能”。
输出格式:
对于每一个询问,输出true,false或者maybe。
输入输出样例
输入样例:
6
2002 4920
2003 5901
2004 2832
2005 3890
2007 5609
2008 3024
5
2002 2005
2003 2005
2002 2007
2003 2007
2005 2008
输出样例:false
true
false
maybe
false
100%的数据满足:1<=n<=50000, 1<=m<=10000, -109<=yi<=109, 1<=ri<=109
题目
要是你第一眼就觉得是一道线段树的题,那怕是没救了(虽然也可以做),显然我们发现这道题没有修改操作,我们就会想到st表或者前缀和。这道题是求区间最大值,所以果断使用st表。然而瞎操作一波发现并没有那么简单。这道题难的地方和数据结构没啥关系,主要是判断十分恶心。各种条件判断不写对拍根本想不到啊。而且这组样例水得不能再水了。后面询问的年份可以不在前面出现,看看这组样例:1 2000 2000 1 1999 2001,应该输出maybe,然而我第一次re了(偷笑)。所以情况特别多啊,这个等会儿在程序里讲。还有一个点就是离散化,这个很简单数据保证有序,连序都不用排了。然后亲测一个隐藏条件:保证输入询问y1<y2。
代码如下(第一次st表就讲细一点):
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>using namespace std;struct lxy{int rain,year;}data[100005];//存数据int n,m;int st1[100005][20];//判断区间最大值的下表//记得st表数组开双倍bool st2[100005][20];//判断区间是否为连续年份,满足为0,不满足为1int lg[100005];//存每个数的log,向下取整int er(int l,int r,int q)//查找是否存在年份为q,存在返回下表,否则返回0{int mid=(l+r)/2;if(l==r) return l;if(data[mid].year<=q) return er(mid+1,r,q);if(data[mid].year>q) return er(l,mid,q);}int find(int l,int r,int q)//查找年份大于q的最小值下标{if(l>r) return 0;int mid=(l+r)/2;if(q==data[mid].year) return mid;if(data[mid].year<q) return find(mid+1,r,q);else return find(l,mid-1,q);}int ques(int x1,int x2)//查询函数,false返回1,true返回2,maybe返回3{int y1=find(1,n,x1),y2=find(1,n,x2);if(y1==0&&y2==0)//如果两个询问年份都不知道,输出maybe return 3;int z1=er(1,n,x1),z2=er(1,n,x2);while(data[z2].year!=x2&&data[z2].year>=x2)//z2是不超过x2的最大年份下标if(z1>z2)//如果满足,一定是maybe,可以自行脑补 return 3;int p=lg[z2-z1+1];int w;if(data[st1[z1][p]].rain<data[st1[z2-(1<<p)+1][p]].rain)//查找区间最大值的下标 w=st1[z2-(1<<p)+1][p];else w=st1[z1][p];if(y2!=0&&w!=z2)//如果x2知道且最大值下标不为x2,输出false return 1;if(y1!=0)//如果x1知道且x1降雨量比区间最大值小,输出false if(data[y1].rain<=data[w].rain) return 1;if(y1==0||y2==0||st2[z1][p]==1||st2[z2-(1<<p)+1][p]==1)//如果区间是断的,输出maybe return 3;if(y1!=0)//如果x1存在,还要判断x1与区间是否连接 if(data[z1-1].year+1!=data[z1].year) return 3;return 2;//最后输出true}int main(){scanf("%d",&n);int p=2;int t=0;for(int i=1;i<=n;i++)//算log,这样可以O(1)查询咯(虽然查询中的二分也让复杂度变成logn了){if(i<p) lg[i]=t;else{ p=p<<1; t++; lg[i]=t; }}for(int i=1;i<=n;i++){scanf("%d%d",&data[i].year,&data[i].rain);st1[i][0]=i;} for(int j=1;j<=15;j++)//st表初始化,j大小数据范围:2^j<数据个数,不然容易超界 for(int i=1;i<=n;i++) { if(data[st1[i][j-1]].rain<data[st1[i+(1<<(j-1))][j-1]].rain) st1[i][j]=st1[i+(1<<(j-1))][j-1]; else st1[i][j]=st1[i][j-1]; if(data[i+(1<<(j-1))-1].year+1!=data[i+(1<<(j-1))].year) st2[i][j]=1; else st2[i][j]=st2[i][j-1]|st2[i+(1<<(j-1))][j-1]; }scanf("%d",&m);for(int i=1;i<=m;i++)//查询询问{int x,y;scanf("%d%d",&x,&y);int ans;ans=ques(x,y);if(ans==1) printf("false\n");if(ans==2) printf("true\n");if(ans==3) printf("maybe\n");}}
这样就完成啦,复杂度是O(n logn)。
阅读全文
0 0
- scoi2007降雨量
- 【SCOI2007】降雨量
- [SCOI2007]降雨量
- [bzoj][SCOI2007]降雨量
- bzoj1067: [SCOI2007]降雨量
- 【BZOJ 1067】 [SCOI2007]降雨量
- 【SCOI2007】【BZOJ1067】降雨量
- [BZOJ1067][SCOI2007]降雨量
- 1067: [SCOI2007]降雨量
- bzoj 1067: [SCOI2007]降雨量
- bzoj 1067 [SCOI2007]降雨量
- bzoj[SCOI2007]降雨量
- 【bzoj1067】[SCOI2007]降雨量
- bzoj 1067: [SCOI2007]降雨量
- 【bzoj1067】[SCOI2007]降雨量
- BZOJ1067[SCOI2007]降雨量
- 【bzoj1067】[SCOI2007]降雨量 (RMQ)
- [bzoj] 1067: [SCOI2007]降雨量
- 【笔试题】
- 日常工作总结
- 奇偶数排序
- 使用OwnCloud建立属于自己的私有的云存储网盘(百度网盘)
- OpenGL图形渲染管线图解
- [SCOI2007]降雨量
- HDOJ 2103 Family planning
- 4用于cifar10的卷积神经网络-4.13优化器FtrlOptimizer的汇总结果分析
- 用jad反编译jar包经验
- Debug: babel arrow function 'unexpected token' in React.Component
- vs2010,vs2015,快捷备注,快捷取消
- Android JNI mkdir文件夹权限
- ACdream
- thinkphp3.2 home为默认模块,在url里面隐藏掉home