BZOJ1067 [SCOI2007]降雨量 RMQ???

求救!!!神犇帮我瞅瞅呗。。。未完。。。调了2个半小时线段树,没调出来,大家帮帮我啊!!!

小詹用st表写。

我的思路就是把中间空着的年份设为无限,然后一点点特判就行了。。。然而没出来。。。

[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

Sample Output

false
true
false
maybe
false

HINT

100%的数据满足:1<=n<=50000, 1<=m<=10000, -10^9<=yi<=10^9, 1<=ri<=10^9

我的凉凉线段树代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(int i = a;i <= n;i++)
#define lv(i,a,n) for(int i = a;i >= n;i--)
#define clean(a) memset(a,0,sizeof(a))
const int INF = << ;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
char c;
bool op = ;
while(c = getchar(), c < '' || c > '')
if(c == '-') op = ;
x = c - '';
while(c = getchar(), c >= '' && c <= '')
x = x * + c - '';
if(op) x = -x;
}
template <class T>
void write(T x)
{
if(x < ) putchar('-'), x = -x;
if(x >= ) write(x / );
putchar('' + x % );
}
int z = ,n,len = ;
int rain[],pl[],ans = ;
int tree[],name[];
void build(int o,int l,int r)
{
if(l == r)
{
tree[o] = rain[l];
name[o] = l;
return;
}
int mid = (l + r) >> ;
build(o << ,l,mid);
build(o << | ,mid + ,r);
if(tree[o << ] > tree[o << | ])
{
tree[o] = tree[o << ];
name[o] = name[o << ];
}
else if(tree[o << ] < tree[o << | ])
{
tree[o] = tree[o << | ];
name[o] = name[o << | ];
}
else
{
tree[o] = INF;
// name[o] = 0;
}
}
int query(int o,int l,int r,int x,int y)
{
cout<<l<<" "<<r<<" "<<x<<" "<<y<<" "<<o<<endl;
if(l == x && r == y)
{
ans = name[o];
cout<<tree[o]<<endl;
if(tree[o] == INF)
{
if(l != r)
{
int mid = (l + r) / ;
return max(query(o * ,l,mid,l,mid),query(o * ,mid + ,r,mid + ,r));
}
else
return -;
}
return tree[o];
}
int mid = (l + r) >> ;
if(y <= mid)
{
return query(o * ,l,mid,x,y);
}
else if(mid < x)
return query(o * + ,mid + ,r,x,y);
else
{
return max(query(o * ,l,mid,x,mid),query(o * + ,mid + ,r,mid + ,y));
}
}
int judge(int l,int r)
{
z = ;
int x = query(,,len,l + ,r);
cout<<x<<endl;
if(x == rain[r] && z == )
return ;
else if(x == rain[r])
return ;
else
return ;
}
int main()
{
read(n);
int x,y;
duke(i,,n)
{
read(x);read(y);
if(pl[len] != x - && i != )
{
int k = pl[len];
pl[++len] = k + ;
rain[len] = INF;
// cout<<len<<" "<<rain[len]<<endl;
}
pl[++len] = x;
rain[len] = y;
}
build(,,len);
// printf("%d %d\n",tree[1],name[1]);
int m;
read(m);
duke(i,,m)
{
read(x);read(y);
int p = lower_bound(pl + ,pl + len + ,x) - pl;
int q = lower_bound(pl + ,pl + len + ,y) - pl;
cout<<p<<" "<<q<<endl;
int t = judge(p,q);
if(t == )
{
printf("true\n");
}
else if(t == )
{
printf("maybe\n");
}
else
{
printf("false\n");
}
}
return ;
}
/*
6
2002 4920
2003 5901
2004 2832
2005 3890
2007 5609
2008 3024
5
2002 2005
2003 2005
2002 2007
2003 2007
2005 2008
*/
/*
6
2002 4920
2003 5901
2004 2832
2005 3890
2007 5609
2008 3024
2
2002 2007
2003 2007
*/

小詹的st表算法:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<stack>
#include<queue>
#include<vector>
#include<cctype>
using namespace std;
#define space putchar(' ')
#define enter puts("")
#define Mem(a) memset(a, 0, sizeof(a))
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-;
const int maxn = 5e4 + ;
inline ll read()
{
ll ans = ;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) {last = ch; ch = getchar();}
while(isdigit(ch)) {ans = (ans << ) + (ans << ) + ch - ''; ch = getchar();}
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < ) putchar('-'), x = -x;
if(x >= ) write(x / );
putchar(x % + '');
} int n, m, a[maxn], yr[maxn]; int dp[maxn][], b[maxn];
void rmq()
{
for(int i = ; i <= n; ++i) dp[i][] = a[i];
for(int j = ; ( << j) <= n; ++j)
for(int i = ; i + ( << j) - <= n; ++i)
dp[i][j] = max(dp[i][j - ], dp[i + ( << (j - ))][j - ]);
int x = ;
for(int i = ; i <= n; ++i)
{
b[i] = x;
if(( << (x + )) <= i + ) x++;
}
}
int query(int L, int R)
{
int k = b[R - L + ];
return max(dp[L][k], dp[R - ( << k) + ][k]);
} int main()
{
n = read();
for(int i = ; i <= n; ++i) yr[i] = read(), a[i] = read();
rmq();
m = read();
for(int i = ; i <= m; ++i)
{
int y = read(), x = read();
if(x <= y) printf("false\n");
else
{
int L = lower_bound(yr + , yr + n + , y) - yr;
int R = lower_bound(yr + , yr + n + , x) - yr;
bool fl = yr[L] == y, fr = yr[R] == x;
int ans = ;
if(L + (fl ? : ) <= R - ) ans = query(L + (fl ? : ), R - ); //别忘了这个判断啊……
if((fr && ans >= a[R]) || (fl && ans >= a[L]) || (fl && fr && (a[L] < a[R] || ans >= a[R]))) printf("false\n");
else if(R - L != yr[R] - yr[L] || !fl || !fr) printf("maybe\n");
else printf("true\n");
}
}
return ;
}
上一篇:BZOJ_1067_[SCOI2007]降雨量_ST表


下一篇:Linux下Tomcat服务器重启与关闭