第四个点(测试数据#3)总是WA

已经交了了二十七遍了(好吧我承认绝大部分是错的)
我一直以为是程序有问题, 直到我在BZOJ上找到原题以及数据
然后一样的源码交了, AC...
难道Vijos测试数据和BZOJ、省选数据不一样吗

膜拜一下以前AC以及测试点#3AC的大神们
怎么做到的……

还是发一下代码吧(线段树查询区间最大值)

#include <cstdio>
#define MAXN 65536
using namespace std;

int n, m;
int rain[(MAXN << 1) + 10], M;
int year[50010];
int s, t, X, Y;
bool flag, findx, findy;

inline void scan(int &x); //读优什么的不要在意
inline int max(int x, int y);
inline void push_up(int n); //线段树.左子树右子树的最大值更新到父节点
inline void build(int n); //建树
inline int search(int x); //好像略复杂, 自己理解...
inline int query(int s, int t); //查询区间最大值

int main(int argc, char **argv) {
scan(n); build(n);
scan(m);
while (m--) {
scan(Y); scan(X);
if (Y > year[n] || X < year[1]) { printf("maybe\n"); continue; }
s = search(Y); if (!(findy=flag)) ++s;
t = search(X); findx = flag;
/* 下面两行判断是压过代码的, 原来的详见下面的下面的下面 */
if (findx && findy && (X == Y || t - s == year[t] - year[s] && rain[t + M] <= rain[s + M] && query(s + 1, t - 1) < rain[t + M])) { printf("true\n"); continue; }
if ((findx ^ findy && (findx ? query(s, t - 1) >= rain[t + M] : query(s + 1, t) >= rain[s + M])) || findx && findy && (rain[t + M] > rain[s + M] || query(s + 1, t - 1) >= rain[t + M])) { printf("false\n"); continue; }
printf("maybe\n");
}
return 0;
}

inline void scan(int &x) {
char c;
while (((c = getchar()) < '0' || c > '9') && c != '-');
bool f = c == '-'; if (f) x = 0; else x = c - '0';
while ((c = getchar()) >= '0' && c <= '9') (x *= 10) += c - '0';
if (f) x = -x;
}

inline int max(int x, int y) {
if (x > y) return x; else return y;
}

inline void push_up(int n) {
rain[n] = max(rain[n << 1], rain[n << 1 | 1]);
}

inline void build(int n) {
for (M = 1; M < n + 2; M <<= 1);
for (int i = M + 1; i <= M + n; ++i) {
scan(year[i - M]); scan(rain[i]);
}
for (int i = M - 1; i > 0; --i) push_up(i);
}

inline int search(int x) {
int l = 1, r = n, m = (l + r) >> 1;
while (l <= r && year[m] != x)
if (x < year[m]) r = m - 1, m = (l + r) >> 1;
else if (x > year[m]) l = m + 1, m = (l + r) >> 1;
if (x == year[m]) flag = true;
else if (l > r) flag = false;
return m;
}

inline int query(int s, int t) {
int ret = 0;
for (s += M - 1, t += M + 1; s ^ t ^ 1; s >>= 1, t >>= 1) {
if (~s & 1) ret = max(ret, rain[s ^ 1]);
if (t & 1) ret = max(ret, rain[t ^ 1]);
}
return ret;
}
/* 下面是原来没压过的判断的代码 */
if (X == Y)
if (findx && findy) printf("true\n");
else printf("maybe\n");
else
if (!findx)
if (!findy) printf("maybe\n");
else
if (query(s + 1, t) >= rain[s + M]) printf("false\n");
else printf("maybe\n");
else
if (!findy)
if (query(s, t - 1) >= rain[t + M]) printf("false\n");
else printf("maybe\n");
else
if (rain[s + M] > rain[s + M] || query(s + 1, t - 1) >= rain[t + M]) printf("false\n");
else
if (t - s == year[t] - year[s]) printf("true\n");
else printf("maybe\n");

求大神指点Orz

1 条评论

  • @ 2014-07-18 10:41:01

    额/* 下面是原来没压过的判断的代码 */部分的倒数第五行有错
    if (rain[s + M] > rain[t + M] || query(s + 1, t - 1) >= rain[t + M]) printf("false\n");

  • 1

信息

ID
1265
难度
8
分类
数据结构 | 线段树 点击显示
标签
递交数
434
已通过
40
通过率
9%
被复制
4
上传者