zoukankan      html  css  js  c++  java
  • BZOJ 1067 降雨量(RMQ-ST+有毒的分类讨论)

    1067: [SCOI2007]降雨量

    Time Limit: 1 Sec  Memory Limit: 162 MB
    Submit: 4399  Solved: 1182
    [Submit][Status][Discuss]

    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

     

     

    题目链接:BZOJ 1067

    这题的分类讨论简直要死,WA很多次才过了,先用RMQ处理出一段区间内的降雨量最大值,然后由于不仔细审题,以为只要y+1~x-1这一段区间内的降雨量严格小于x即可,实际上除了这个条件还需要x的降雨量小于等于y的降雨量:它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小于X年然后分类讨论区间是否合法,我写的辣鸡代码量比较多,但是感觉比较清楚

    代码:

    #include <stdio.h>
    #include <bits/stdc++.h>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define LC(x) (x<<1)
    #define RC(x) ((x<<1)+1)
    #define MID(x,y) ((x+y)>>1)
    #define CLR(arr,val) memset(arr,val,sizeof(arr))
    #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
    typedef pair<int, int> pii;
    typedef long long LL;
    const double PI = acos(-1.0);
    const int N = 50010;
    struct info
    {
    	int year;
    	int val;
    };
    info arr[N];
    int maxm[N << 1][20];
    map<int, int>vis;
    
    void RMQ_init(int l, int r)
    {
    	int i, j;
    	for (i = l; i <= r; ++i)
    		maxm[i][0] = arr[i].val;
    	for (j = 1; l + (1 << j) - 1 <= r; ++j)
    		for (i = l; i + (1 << j) - 1 <= r; ++i)
    			maxm[i][j] = max(maxm[i][j - 1], maxm[i + (1 << (j - 1))][j - 1]);
    }
    int ST(int l, int r)
    {
    	int k = log2(r - l + 1);
    	return max(maxm[l][k], maxm[r - (1 << k) + 1][k]);
    }
    int Find(int year, int l, int r)
    {
    	int L = l, R = r, ans = 0;
    	while (L <= R)
    	{
    		int mid = (L + R) >> 1;
    		if (arr[mid].year == year)
    		{
    			ans = mid;
    			break;
    		}
    		else if (arr[mid].year < year)
    			L = mid + 1;
    		else
    			R = mid - 1;
    	}
    	return ans;
    }
    int Find_Lpos(int year, int l, int r)//相当于lower_bound
    {
    	int L = l, R = r, ans = 0;
    	while (L <= R)
    	{
    		int mid = (L + R) >> 1;
    		if (arr[mid].year >= year)
    		{
    			ans = mid;
    			R = mid - 1;
    		}
    		else
    			L = mid + 1;
    	}
    	return ans;
    }
    int Find_Rpos(int year, int l, int r)//相当于upper_bound - 1
    {
    	int L = l, R = r, ans = 0;
    	while (L <= R)
    	{
    		int mid = (L + R) >> 1;
    		if (arr[mid].year <= year)
    		{
    			ans = mid;
    			L = mid + 1;
    		}
    		else
    			R = mid - 1;
    	}
    	return ans;
    }
    int main(void)
    {
    	int n, m, i, x, y;
    	while (~scanf("%d", &n))
    	{
    		vis.clear();
    		for (i = 1; i <= n; ++i)
    		{
    			scanf("%d%d", &arr[i].year, &arr[i].val);
    			vis[arr[i].year] = arr[i].val;
    		}
    		RMQ_init(1, n);
    		scanf("%d", &m);
    		for (i = 0; i < m; ++i)
    		{
    			scanf("%d%d", &y, &x);
    			if (vis[y] && vis[x])
    			{
    				int L = Find(y, 1, n);
    				int R = Find(x, 1, n);
    				if (arr[R].val > arr[L].val) //保证Fx<=Fy
    					puts("false");
    				else if (R - L + 1 == x - y + 1) //中间年份全
    				{
    					if (L + 1 > R - 1) //年份相邻
    						puts("true");
    					else//至少隔了一个单位
    					{
    						int ma = ST(L + 1, R - 1);
    						if (ma < arr[R].val)
    							puts("true");
    						else
    							puts("false");
    					}
    				}
    				else//中间年份残缺
    				{
    					if (L + 1 > R - 1) //输入顺序相邻
    						puts("maybe");
    					else//至少隔了一个输入单位
    					{
    						int ma = ST(L + 1, R - 1);
    						if (ma < arr[R].val)
    							puts("maybe");
    						else
    							puts("false");
    					}
    				}
    			}
    			else if (vis[y] && !vis[x]) //y已知x未知
    			{
    				int L = Find(y, 1, n);
    				int R = Find_Rpos(x, 1, n);
    				if (L == R)
    					puts("maybe");
    				else if (L == R - 1)
    				{
    					if (arr[R].val < arr[L].val)
    						puts("maybe");
    					else
    						puts("false");
    				}
    				else
    				{
    					int ma = ST(L + 1, R);
    					if (ma < arr[L].val)
    						puts("maybe");
    					else
    						puts("false");
    				}
    			}
    			else if (!vis[y] && vis[x]) //y未知x已知
    			{
    				int L = Find_Lpos(y, 1, n);
    				int R = Find(x, 1, n);
    				if (L == R)
    					puts("maybe");
    				else
    				{
    					int ma = ST(L, R - 1);
    					if (ma < arr[R].val)
    						puts("maybe");
    					else
    						puts("false");
    				}
    			}
    			else//均未知,一定是maybe
    				puts("maybe");
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    ActiveSync合作关系对话框的配置
    WINCE对象存储区(object store)
    Wince 隐藏TASKBAR的方法
    Wince输入法换肤换语言机制
    poj 3080 Blue Jeans 解题报告
    codeforces A. Vasily the Bear and Triangle 解题报告
    hdu 1050 Moving Tables 解题报告
    hdu 1113 Word Amalgamation 解题报告
    codeforces A. IQ Test 解题报告
    poj 1007 DNA Sorting 解题报告
  • 原文地址:https://www.cnblogs.com/Blackops/p/6354251.html
Copyright © 2011-2022 走看看