# 明明都是我先來的... https://neoj.sprout.tw/problem/752/ ![](https://i.imgur.com/pPQ8nmJ.png) > 是我,是我先,明明都是我先來的...... -- [冬馬和紗](https://zh.moegirl.org.cn/%E5%86%AC%E9%A9%AC%E5%92%8C%E7%BA%B1) (@[白色相簿2](https://zh.moegirl.org.cn/%E7%99%BD%E8%89%B2%E7%9B%B8%E7%B0%BF2)) > 白色相簿什麼的已經無所謂了。因為已經不再有歌,值得去唱了。傳達不了的戀情已經不需要了。因為已經不再有人,值得去愛了。 ホワイトアルバムなんて知らない。だって、もう何も歌えない。届かない恋なんてしない。だって、もう人を愛せない。 [name=《白色相簿2》終章官方宣傳詞][color=lightblue] > 為什麼你會這麼熟練啊!你和雪菜親過多少次了啊!?你到底要把我甩開多遠你才甘心啊!? なんでそんなに慣れてんだよっ!雪菜と…何回キスしたんだよ!?どこまであたしを置いてきぼりにすれば気が済むんだよ!? [name=冬馬和紗, 第11話][color=lightblue] > 是我,是我先,明明都是我先來的……接吻也好,擁抱也好,還是喜歡上那傢伙也好。 あたしが、先だった……先だったんだ……キスしたのも、抱き合ったのも。そいつのこと好きになったのも。 [name=冬馬和紗][color=lightblue] > 為什麼會變成這樣呢……第一次有了喜歡的人。有了能做一輩子朋友的人。兩件快樂事情重合在一起。而這兩份快樂,又給我帶來更多的快樂。得到的,本該是像夢境一般幸福的時間……但是,為什麼,會變成這樣呢…… どうしてこうなるんだろう…初めて、好きな人が出来た。一生ものの友だちができた。嬉しいことが二つ重なって。その二つの嬉しさが、また、たくさんの嬉しさを連れてきてくれて。夢のように幸せな時間を手に入れたはずなのに…なのに、どうして、こうなっちゃうんだろう… [name=小木曾雪菜][color=lightblue] ### 輸入格式 + 第一行兩個整數N, M,分別代表著有N個人(編號從0 ~ N-1)以及M對喜歡關係。 + 其中這個M對是按照時間順序所排列的,保證一個人不會重複喜歡同個人,也不會喜歡自己。但是有可能他會同時喜歡很多人。 + 接下來M行,每行有兩個數字,分別代表著被喜歡的人以及喜歡的人。 ### 輸出格式 + 請輸出N行,每行內輸出他們的編號,之後依序輸出到底有誰喜歡這個人。 (需要按照時間排列) + 例如現在2, 3, 4喜歡1,那麼當輸出到1這個人的時候會長得像這樣1: 2 3 4這樣。注意,每行不能有結尾空格。 + 如果這個人很可憐,沒有人愛他,那就不要在鞭屍他了。這種情況不要為他輸出東西。(以範例測資的話,0這個人沒人愛,就不要輸出他。) ### 提示 + 這題最基礎的作法是直接開一個NxN的二維陣列,然後每看到一組(a,b),就把b放到第a列當前的最後一個。例如假設現在有(1, 2), (2, 3), (1, 4)的組合,二維陣列可能會像這樣: + ary[1] 有兩個數字: 2, 4 + ary[2] 有一個數字: 3 + 而因為可能所有人都同時喜歡同一個人,所以陣列的第二維度宣告可能要開到最大,即為N。 + 但如果當N太大,你就無法開成這樣(因為沒有那麼多的空間)。所以我們會用神奇的方法存下來。這個神奇的方法我們已經幫妳寫好了,你能看懂並利用它嗎? + 你不需要寫出整份程式,你只需要實作print函數。你的程式會在附圖code上插入: ```cpp #include <iostream> #include <cassert> #define MAXN 100000 #define MAXM 1000000 using namespace std; typedef struct person{ int count; int *loved_begin; }person; int storage[MAXM]; person all_people[MAXN]; int pairs[MAXM][2]; int now_cnt[MAXN] = {0}; void prepare(int n, int m, person *all_people, int *storage){ // input for(int i=0; i<m; i++) cin >> pairs[i][0] >> pairs[i][1]; // initialization for(int i=0; i<n; i++) all_people[i].count = 0; // calculate_count for(int i=0; i<m; i++) all_people[pairs[i][0]].count++; ​ // calculate start int now_start = 0; for(int i=0; i<n; i++){ all_people[i].loved_begin = storage+now_start; now_start += all_people[i].count; } ​ // push element into storage for(int i=0; i<m; i++){ int be_loved = pairs[i][0], to_love = pairs[i][1]; int now_filled_position = now_cnt[be_loved]; person be_loved_person = all_people[be_loved]; (be_loved_person.loved_begin)[now_filled_position] = to_love; // next position move to next now_cnt[be_loved]++; } ​ // destroy the elements for(int i=0; i<m; i++) pairs[i][0] = pairs[i][1] = 0; ​ } void print(int, int, person *, int *); int main(){ int n, m; cin >> n >> m; prepare(n, m, all_people, storage); print(n, m, all_people, storage); return 0; } #include "main.cpp" /* 你的code會被放在這裡。 */ ``` ### 輸入限制 + $0 < N < 10^5$ + $0 < M < 10^6$ + 接下來M個配對的所有數字都會介於0 ~ N-1之間。 ### 範例輸入 ``` 4 5 1 2 2 3 1 3 3 1 2 0 ``` ### 範例輸出 ``` 1: 2 3 2: 3 0 3: 1 ``` # Code ```cpp void print(int n, int m, person *all_people, int *storage){ for (int i = 0; i < n; i++) { if (all_people[i].count == 0) continue; cout << i << ":"; person be_loved_person = all_people[i]; for (int j = 0; j < all_people[i].count; j++) cout << " " << be_loved_person.loved_begin[j]; cout << "\n"; } } ```