洛谷 P2058 海港 解題報告
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\)
輸入輸出格式
輸入格式:
第一行輸入一個正整數\(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\)
輸出格式:
輸出\(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 海港 解題報告