zoukankan      html  css  js  c++  java
  • [BZOJ1067][SCOI2007]降雨量

    [BZOJ1067][SCOI2007]降雨量

    试题描述

    我们常常会说这样的话:“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, -10^9<=yi<=10^9, 1<=ri<=10^9

    题解

    分类讨论。

    本题考点:if 语句的应用。本题难点:分类讨论的完整性。

    被 lower_bound 坑了,lower_bound 找的是大于等于 x 的最小值,我给记成小于等于 x 的最大值了。。。。。。。。。。。。。。。。。。。。。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <stack>
    #include <vector>
    #include <queue>
    #include <cstdlib>
    using namespace std;
    
    const int BufferSize = 1 << 16;
    char buffer[BufferSize], *Head, *tail;
    inline char Getchar() {
        if(Head == tail) {
            int l = fread(buffer, 1, BufferSize, stdin);
            tail = (Head = buffer) + l;
        }
        return *Head++;
    }
    int read() {
    	int x = 0, f = 1; char c = Getchar();
    	while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
    	while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
    	return x * f;
    }
    
    #define maxn 50010
    int n, q, year[maxn], rain[maxn];
    
    int maxv[maxn<<2], mxy[maxn<<2], mny[maxn<<2];
    bool iss[maxn<<2];
    void build(int L, int R, int o) {
    	if(L == R) maxv[o] = rain[L], mxy[o] = mny[o] = year[L], iss[o] = 1;
    	else {
    		int M = L + R >> 1, lc = o << 1, rc = lc | 1;
    		build(L, M, lc); build(M+1, R, rc);
    		maxv[o] = max(maxv[lc], maxv[rc]);
    		iss[o] = iss[lc] & iss[rc] & (mxy[lc] - mny[rc] == -1);
    		mny[o] = mny[lc]; mxy[o] = mxy[rc];
    	}
    	return ;
    }
    int _o[maxn<<2], cnt;
    int query(int L, int R, int o, int ql, int qr) {
    	if(ql > qr) return -1;
    	if(ql <= L && R <= qr) {
    		_o[++cnt] = o;
    		return maxv[o];
    	}
    	int M = L + R >> 1, lc = o << 1, rc = lc | 1, ans = 0;
    	if(ql <= M) ans = max(ans, query(L, M, lc, ql, qr));
    	if(qr > M) ans = max(ans, query(M+1, R, rc, ql, qr));
    	return ans;
    }
    bool qq() {
    	bool ok = 1;
    	for(int i = 1; i <= cnt; i++) ok &= iss[_o[i]];
    	for(int i = 1; i < cnt; i++) ok &= (mxy[_o[i]] - mny[_o[i+1]] == -1);
    	return ok;
    }
    
    int main() {
    	n = read();
    	for(int i = 1; i <= n; i++) year[i] = read(), rain[i] = read();
    	build(1, n, 1);
    	q = read();
    	while(q--) {
    		int yl = read(), yr = read(),
    		ql = lower_bound(year + 1, year + n + 1, yl) - year,
    		qr = lower_bound(year + 1, year + n + 1, yr) - year;
    		if(year[ql] != yl) ql--;
    		if(year[qr] != yr) qr--;
    		int ans; cnt = 0;
    		if(yl > yr){ puts("false"); continue; }
    		if(yl == yr){ puts("true"); continue; }
    		if(yl >= year[n]){ puts("maybe"); continue; }
    		if(yr <= year[1]){ puts("maybe"); continue; }
    		if(yl < year[1] && yr > year[n]){ puts("maybe"); continue; }
    		if(year[ql] == yl && yr > year[n] && query(1, n, 1, ql+1, n) >= rain[ql]){ puts("false"); continue; }
    		if(year[ql] != yl && yr > year[n]){ puts("maybe"); continue; }
    		if(year[qr] == yr && yl < year[1] && query(1, n, 1, 1, qr-1) >= rain[qr]){ puts("false"); continue; }
    		if(year[qr] != yr && yl < year[1]){ puts("maybe"); continue; }
    		if(yl == yr - 1) {
    			if(year[ql] == yl && year[qr] == yr) {
    				if(rain[ql] >= rain[qr]) puts("true");
    				else puts("false");
    			}
    			else puts("maybe");
    			continue;
    		}
    		if(year[ql] == yl && year[qr] == yr && rain[ql] >= rain[qr] && query(1, n, 1, ql+1, qr-1) < rain[qr]) {
    			cnt = 0; query(1, n, 1, ql, qr);
    			if(qq()){ puts("true"); continue; }
    		}
    		if(year[ql] == yl && year[qr] == yr) {
    			if(rain[ql] < rain[qr]){ puts("false"); continue; }
    			if(query(1, n, 1, ql+1, qr-1) >= rain[qr]){ puts("false"); continue; }
    		}
    		if(year[ql] == yl && query(1, n, 1, ql+1, qr) >= rain[ql]){ puts("false"); continue; }
    		if(year[qr] == yr && query(1, n, 1, ql+1, qr-1) >= rain[qr]){ puts("false"); continue; }
    		puts("maybe");
    	}
    	
    	return 0;
    }
    
  • 相关阅读:
    nginx 配置上传文件大小限制
    linux大文件截取某个日期后面的所有内容
    软件架构笔记 五
    软件架构笔记 四
    软甲架构笔记 三
    软件架构笔记 二
    软件架构笔记 一
    c# 生成的没用文件
    c# 两个软件传参
    c# 四则运算出错
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/5509551.html
Copyright © 2011-2022 走看看