1. 程式人生 > >洛谷 P2058 海港 解題報告

洛谷 P2058 海港 解題報告

scan == main 一行 並不是 string 24小時 信息 圖片

P2058 海港

題目描述

小K是一個海港的海關工作人員,每天都有許多船只到達海港,船上通常有很多來自不同國家的乘客。

小K對這些到達海港的船只非常感興趣,他按照時間記錄下了到達海港的每一艘船只情況;對於第\(i\)艘到達的船,他記錄了這艘船到達的時間\(t_i\)(單位:秒),船上的乘客數星\(k_i\),以及每名乘客的國籍\(x(i,1), x(i,2),…,x(i,k)\);。

\(K\)統計了\(n\)艘船的信息,希望你幫忙計算出以每一艘船到達時間為止的24小時(24小時=86400秒)內所有乘船到達的乘客來自多少個不同的國家。

形式化地講,你需要計算\(n\)條信息。對於輸出的第i條信息,你需要統計滿足\(t_i-86400<t_p<= t_i\)

的船只\(p\),在所有的\(x(p,j)\)中,總共有多少個不同的數。

輸入輸出格式

輸入格式:
第一行輸入一個正整數\(n\),表示小\(K\)統計了\(n\)艘船的信息。

接下來\(n\)行,每行描述一艘船的信息:前兩個整數\(t_i\)\(k_i\)分別表示這艘船到達海港的時間和船上的乘客數量,接下來\(k_i\)個整數\(x(i,j)\)表示船上乘客的國家。

保證輸入的\(t_i\)是遞增的,單位是秒;表示從小K第一次上班開始計時,這艘船在第\(t_i\)秒到達海港。
保證\(1<=n<=10^5\),\(\sum {k_i}<=3?10^5\),\(1<=x(i,j)<=10^5\)

,\(10^9<=t_{i?1}<=ti<=10^9\)
輸出格式:
輸出\(n\)行,第\(i\)行輸出一個整數表示第\(i\)艘船到達後的統計信息。


昨天聽教練說,普及組的題目不怎麽考算法,我的內心陡然一驚,那豈不是怎麽暴力怎麽來?

事實上並不是那麽簡單的,不考算法,就十分的考思想了,昨天被2016T4魔法陣嚇到了於是打算先寫寫第三題。

今天讀完題目,恩?洛谷高性能?怕不是要卡常?那直接暴力來吧。拿個桶把當前的存起來,把船的信息壓進隊列,交了以後

技術分享圖片

這個,看來事情並沒有這麽簡單,發現人最多有三十萬個,那直接存人和船的時間斷點好了。

技術分享圖片

尷尬,,,

加一個上下界優化好了,每次遍歷桶的時候只遍歷到之前出現過得最大的人。

技術分享圖片

好家夥,不能這樣搞。

又想了想,如果更新桶的時候某個種類由0變成了1就把答案加1,反之減1,不就剛好保證了300000*2嗎

原來正確復雜度是\(O(\sum k)\),所以有時候想練練思想,不妨多做做沒有什麽算法的題目。


#include <cstdio>
#include <cstring>
int max(int x,int y){return x>y?x:y;}
const int N=100010;
int ans[N],n,t,k,tour[N*3],time[N][2],l=1,r,p=1,now;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&t,&k);
        while(time[l][0]<=t-86400&&l<=r)
        {
            for(;p<=time[l][1];p++)
            {
                ans[tour[p]]--;
                if(!ans[tour[p]]) now--;
            }
            l++;
        }
        for(int j=time[r][1]+1;j<=time[r][1]+k;j++)
        {
            scanf("%d",tour+j);
            ans[tour[j]]++;
            if(ans[tour[j]]==1)
                now++;
        }
        time[++r][0]=t;
        time[r][1]=time[r-1][1]+k;
        printf("%d\n",now);
    }
    return 0;
}

2018.6.18

洛谷 P2058 海港 解題報告