1. 程式人生 > >洛谷P2058 海港

洛谷P2058 海港

一行 log vector 一個隊列 img stream 技術分享 printf 很多

題目描述

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

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

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

形式化地講,你需要計算n條信息。對於輸出的第i條信息,你需要統計滿足 ti - 86400 < tp <= ti的船只p,在所有的x(p,j)中,總共有多少個不同的數。

輸入輸出格式

輸入格式:

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

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

保證輸入的ti是遞增的,單位是秒;表示從小K第一次上班開始計時,這艘船在第 ti 秒到達海港。

保證 1 \le n \le 10^51n10?5??,\sum{ki} \le 3*10^5ki3?10?5?? ,1\le x(i,j) \le 10^51x(i,j)10?5??, 1 \le t(i-1)\le ti \le 10^91t(i?1)ti10?9??。(看原題)

其中\sum{ki}ki表示所有的ki的和。

輸出格式:

輸出n行,第i行輸出一個整數表示第i艘船到達後的統計信息。

輸入輸出樣例

輸入樣例#1:
3
1 4 4 1 2 2
2 2 2 3
10 1 3
輸出樣例#1:
3
4
4
輸入樣例#2:
4
1 4 1 2 2 3
3 2 2 3
86401 2 3 4
86402 1 5
輸出樣例#2:
3
3
3
4

說明

【樣例解釋1】

第一艘船在第1秒到達海港,最近24小時到達的船是第一艘船,共有4個乘客, 分別是來自國家4,1,2,2,共來自3個不同的國家;

第二艘船在第2秒到達海港,最近24小時到達的船是第一艘船和第二艘船,共有 4 + 2 = 6個乘客,分別是來自國家4,1,2,2,2,3,共來自4個不同的國家;

第三艘船在第10秒到達海港,最近24小時到達的船是第一艘船、第二艘船和第 三艘船,共有4+ 2+1=7個乘客,分別是來自國家4,1,2,2,2,3,3,共來自4個不同 的國家。

【樣例解釋2】

第一艘船在第1秒到達海港,最近24小時到達的船是第一艘船,共有4個乘客,分別是來自國家1,2,2,3,共來自3個不同的國家。

第二艘船在第3秒到達海港,最近24小時到達的船是第一艘船和第二艘船,共有4+2=6個乘客,分別是來自國家1,2,2,3,2,3,共來自3個不同的國家。

第三艘船在第86401秒到達海港,最近24小時到達的船是第二艘船和第三艘船,共有2+2=4個乘客,分別是來自國家2,3,3,4,共來自3個不同的國家。

第四艘船在第86402秒到達海港,最近24小時到達的船是第二艘船、第三艘船和第四艘船,共有2+2+1=5個乘客,分別是來自國家2,3,3,4,5,共來自4個不同的國家。

【數據範圍】

技術分享

分析:直接做是過不了的,但是它就是不斷的將先來的弄出去,相當於隊列一樣用一個隊列維護時間t,每次看隊首元素有沒有相隔24小時如果有,則l++,否則入隊統計.對於數據的存儲可能有點困難,n*∑ki的數組是開不下的,但是他是按照每艘船的順序給出來的,如果可以轉化為一條鏈就好了.第一個方法是vector,似乎有點慢第二個方法是queue,這個可以用數組模擬,效率比較高.每次刪除一條船就都從隊列中刪除信息,開一個vis數組記錄一下人數這裏是不能用bool數組或者每次都掃一下vis數組的,我們可以動態改變答案 前綴和也是行不通的,不能滿足區間減性質.

當數組大小是n*m這種乘積類型時,可以考慮能不能轉化成一條鏈狀的形式。動態統計答案是一種有效處理多次統計答案的問題的方式。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>

using namespace std;

int n,num[1000010],vis[1000010],ans;

struct node
{
   int id,t;    
};

int main()
{
    scanf("%d",&n);
    queue <node> qt;
    queue <int> q;
    for (int i = 1; i <= n; i++)
    {
        int t;
        scanf("%d%d",&t,&num[i]);
        node temp;
        temp.id = i;
        temp.t = t;
        qt.push(temp);
        for (int j = 1; j <= num[i];j++)
        {
            int x;
            scanf("%d",&x);
            q.push(x);
            if (vis[x] == 0)
            ans++;
            vis[x]++;
        }
        
        while (!qt.empty() && qt.front().t <= t - 86400)
        {        
            node u = qt.front();
            qt.pop();
            for (int j = 1; j <= num[u.id]; j++)
            {
            vis[q.front()]--;
            if (vis[q.front()] == 0)
            ans--;
            q.pop();
            }
        }
        printf("%d\n",ans);
    }
    
    
    return 0;
}

洛谷P2058 海港