codevs 2439 降雨量 (RMQ+離散化+令人窒息的分類討論)

來源:互聯網
上載者:User

題目描述 Description

我們常常會說這樣的話:“X年是自Y年以來降雨量最多的”。它的含義是X年的降雨量不超過Y年,且對於任意Y<Z<X,Z年的降雨量嚴格小於X年。例如2002,2003,2004和2005年的降雨量分別為4920,5901,2832和3890,則可以說“2005年是自2003年以來最多的”,但不能說“2005年是自2002年以來最多的”由於有些年份的降雨量未知,有的說法是可能正確也可以不正確的。 輸入描述 Input Description

輸入僅一行包含一個正整數n,為已知的資料。以下n行每行兩個整數yi和ri,為年份和降雨量,按照年份從小到大排列,即yi<yi+1。下一行包含一個正整數m,為詢問的次數。以下m行每行包含兩個數Y和X,即詢問“X年是自Y年以來降雨量最多的。”這句話是必真、必假還是“有可能”。 輸出描述 Output Description

對於每一個詢問,輸出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 資料範圍及提示 Data Size & Hint

100%的資料滿足:1<=n<=50000, 1<=m<=10000, -109<=yi<=109, 1<=ri<=109

借鑒了一大佬的部落格  http://www.cnblogs.com/CQzhangyu/p/6878335.html 分析:首先先離散化處理資料,然後開始令人窒息的分類討論

true的條件很嚴苛,只有當左右端點已知,且左端點大於等於右端點的值,中間年份最大值已知,且小於右端點的值,且年份連續

maybe的條件有很多

1:左右端點都不知 2:左端點已知,右端點未知,中間最大值小於左端點值 3:右端點已知,左端點未知,中間最大值小於右端點值 4:中間最大值未知,左端點值大於右端點值 :5:只有當左右端點已知,且左端點大於等於右端點的值,中間年份最大值已知,且小於右端點的值,但年份不連續

false的條件有1:左端點年份大於等於右端點年份 2:以上的其他都為false

對於這題一定要細心。。。

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#define MAX_N 70005#define INF 1000000005using namespace std;int dp[MAX_N][20],q[10005][2],s[MAX_N],vis[MAX_N];struct node{    int y,k,org;}a[MAX_N];bool cmp(node a, node b){    return a.y<b.y;}int main(){    int n,m,cnt=0;    scanf("%d",&n);    for(int i=1;i<=n;i++)        scanf("%d%d",&a[i].y,&a[i].k);    scanf("%d",&m);    for(int i=1;i<=m;i++)        scanf("%d%d",&a[n+2*i-1].y,&a[n+2*i].y),a[n+2*i-1].org=a[n+2*i].org=i,a[n+2*i].k=1,a[n+2*i-1].k=0;    sort(a+1,a+1+n+2*m,cmp);    vis[0]=-INF,s[0]=0;    for(int i=1;i<=n+2*m;i++)    {        if(a[i].y>vis[cnt]) vis[++cnt]=a[i].y,s[cnt]=s[cnt-1];        if(a[i].org) q[a[i].org][a[i].k]=cnt;        else dp[cnt][0]=a[i].k,s[cnt]++;    }    for(int j=1;(1<<j)<=cnt;j++)        for(int i=1;i+(1<<j)-1<=cnt;i++)            dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);    for(int i=1;i<=m;i++)    {        int ql=q[i][0],qr=q[i][1],maxn,flag=0,len=qr-ql-1;        int k=log2(len);        if(ql+1>qr-1) maxn=0;        else maxn=max(dp[ql+1][k],dp[qr-(1<<k)][k]);        if(vis[qr]-vis[ql]==s[qr]-s[ql]) flag=1;        if(ql>=qr) printf("false\n");        else if(dp[ql][0]&&dp[qr][0]&&flag&&dp[ql][0]>=dp[qr][0]&&maxn<dp[qr][0]) printf("true\n");        else if(!dp[ql][0]&&!dp[qr][0]) printf("maybe\n");        else if(dp[ql][0]&&!dp[qr][0]&&maxn<dp[ql][0]) printf("maybe\n");        else if(!dp[ql][0]&&dp[qr][0]&&maxn<dp[qr][0]) printf("maybe\n");        else if(!maxn&&dp[ql][0]>=dp[qr][0]) printf("maybe\n");        else if(dp[ql][0]&&dp[qr][0]&&maxn<dp[qr][0]&&dp[ql][0]>=dp[qr][0]&&!flag) printf("maybe\n");        else printf("false\n");    }    return 0;}



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.