【BZOJ1067】[SCOI2007]降雨量 RMQ+特判
【BZOJ1067】[SCOI2007]降雨量
Description
我们常常会说这样的话:“X年是自Y年以来降雨量最多的”。它的含义是X年的降雨量不超过Y年,且对于任意
Y<Z<X,Z年的降雨量严格小于X年。例如2002,2003,2004和2005年的降雨量分别为4920,5901,2832和3890,
则可以说“2005年是自2003年以来最多的”,但不能说“2005年是自2002年以来最多的”由于有些年份的降雨量未
知,有的说法是可能正确也可以不正确的。
Input
输入仅一行包含一个正整数n,为已知的数据。以下n行每行两个整数yi和ri,为年份和降雨量,按照年份从小
到大排列,即yi<yi+1。下一行包含一个正整数m,为询问的次数。以下m行每行包含两个数Y和X,即询问“X年是
自Y年以来降雨量最多的。”这句话是必真、必假还是“有可能”。
Output
对于每一个询问,输出true,false或者maybe。
Sample Input
6
2002 4920
2003 5901
2004 2832
2005 3890
2007 5609
2008 3024
5
2002 2005
2003 2005
2002 2007
2003 2007
2005 2008
2002 4920
2003 5901
2004 2832
2005 3890
2007 5609
2008 3024
5
2002 2005
2003 2005
2002 2007
2003 2007
2005 2008
Sample Output
false
true
false
maybe
false
true
false
maybe
false
HINT
100%的数据满足:1<=n<=50000, 1<=m<=10000, -10^9<=yi<=10^9, 1<=ri<=10^9
题解:这题没啥说的,就是特判多,可以用离散化+RMQ处理区间最大值,剩下的请见hzwer的题解
还好有小号交题大法~
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; struct node { int v,k,org; }p[70010]; int n,m,nm; int f[70010][20],q[10010][2],Log[70010],ref[70010],s[70010]; bool cmp(node a,node b) { return a.v<b.v; } int query(int a,int b) { if(a>b) return 0; int k=Log[b-a+1]; return max(f[a][k],f[b-(1<<k)+1][k]); } int main() { scanf("%d",&n); int i,j; for(i=1;i<=n;i++) scanf("%d%d",&p[i].v,&p[i].k); scanf("%d",&m); for(i=1;i<=m;i++) scanf("%d%d",&p[i*2-1+n].v,&p[i*2+n].v),p[i*2-1+n].org=p[i*2+n].org=i,p[i*2+n].k=1; sort(p+1,p+n+2*m+1,cmp); ref[0]=-1<<30; for(i=1;i<=n+2*m;i++) { if(p[i].v>ref[nm]) ref[++nm]=p[i].v,s[nm]=s[nm-1]; if(!p[i].org) f[nm][0]=p[i].k,s[nm]++; else q[p[i].org][p[i].k]=nm; } for(j=1;(1<<j)<=nm;j++) for(i=1;i+(1<<j)-1<=nm;i++) f[i][j]=max(f[i][j-1],f[i+(1<<j-1)][j-1]); for(i=2;i<=nm;i++) Log[i]=Log[i>>1]+1; for(i=1;i<=m;i++) { int qa=q[i][0],qb=q[i][1],qx=query(qa+1,qb-1),aa=(ref[qb]-ref[qa]==s[qb]-s[qa]); if(qa>=qb) printf("false\n"); else if(f[qa][0]&&f[qb][0]&&aa&&qx<f[qb][0]&&f[qa][0]>=f[qb][0]) printf("true\n"); else if(!f[qa][0]&&!f[qb][0]) printf("maybe\n"); else if(f[qa][0]&&!f[qb][0]&&qx<f[qa][0]) printf("maybe\n"); else if(!f[qa][0]&&f[qb][0]&&qx<f[qb][0]) printf("maybe\n"); else if(!qx&&f[qa][0]>=f[qb][0]) printf("maybe\n"); else if(f[qa][0]&&f[qb][0]&&qx<f[qb][0]&&f[qa][0]>=f[qb][0]&&!aa) printf("maybe\n"); else printf("false\n"); } return 0; }
| 欢迎来原网站坐坐! >原文链接<